Search code examples
pythonstringencodingint

Python: Reversibly encode alphanumeric string to integer


I want to convert a string (composed of alphanumeric characters) into an integer and then convert this integer back into a string:

string --> int --> string

In other words, I want to represent an alphanumeric string by an integer.

I found a working solution, which I included in the answer, but I do not think it is the best solution, and I am interested in other ideas/methods.

Please don't tag this as duplicate just because a lot of similar questions already exist, I specifically want an easy way of transforming a string into an integer and vice versa.

This should work for strings that contain alphanumeric characters, i.e. strings containing numbers and letters.


Solution

  • Here's what I have so far:

    First define an string

    m = "test123"
    

    string -> bytes

    mBytes = m.encode("utf-8")
    

    bytes -> int

    mInt = int.from_bytes(mBytes, byteorder="big")
    

    int -> bytes

    mBytes = mInt.to_bytes(((mInt.bit_length() + 7) // 8), byteorder="big")
    

    bytes -> string

    m = mBytes.decode("utf-8")
    

    All together

    m = "test123"
    mBytes = m.encode("utf-8")
    mInt = int.from_bytes(mBytes, byteorder="big")
    mBytes2 = mInt.to_bytes(((mInt.bit_length() + 7) // 8), byteorder="big")
    m2 = mBytes2.decode("utf-8")
    print(m == m2)
    

    Here is an identical reusable version of the above:

    class BytesIntEncoder:
    
        @staticmethod
        def encode(b: bytes) -> int:
            return int.from_bytes(b, byteorder='big')
    
        @staticmethod
        def decode(i: int) -> bytes:
            return i.to_bytes(((i.bit_length() + 7) // 8), byteorder='big')
    

    If you're using Python <3.6, remove the optional type annotations.

    Test:

    >>> s = 'Test123'
    >>> b = s.encode()
    >>> b
    b'Test123'
    
    >>> BytesIntEncoder.encode(b)
    23755444588720691
    >>> BytesIntEncoder.decode(_)
    b'Test123'
    >>> _.decode()
    'Test123'