6

I am given this number 427021005928, which i am supposed to change into a base64 encoded string and then decode the base64 string to get a plain text.

This decimal value 427021005928 when converted to binary gives 110001101101100011011110111010001101000 which corresponds to 'Y2xvdGg=', which is what i want. Got the conversion from (https://cryptii.com/pipes/binary-to-base64)

And then finally i decode 'Y2xvdGg=' to get the text cloth.

My problem is i do not have any idea how to use Python to get from either the decimal or binary value to get 'Y2xvdGg='

Some help would be appreciated!

NOTE: I only have this value 427021005928 at the start. I need to get the base64 and plaintext answers.

Moud
  • 61
  • 1
  • 5
  • I'm not getting the same base64 string. Try `import base64; import struct; v=struct.pack('L', v); base64.b64encode(struct.pack('L', v))` – knh190 Mar 26 '19 at 10:10

5 Answers5

4

One elegant way would be using [Python 3]: struct - Interpret bytes as packed binary data, but given the fact that Python numbers are not fixed size, some additional computation would be required (for example, the number is 5 bytes long).

Apparently, the online converter, applied the base64 encoding on the number's memory representation, which can be obtained via [Python 3]: int.to_bytes(length, byteorder, *, signed=False)(endianness is important, and in this case it's big):

For the backwards process, reversed steps are required. There are 2 alternatives:

  • Things being done manually (this could also be applied to the "forward" process)
  • Using int.from_bytes
>>> import base64
>>>
>>> number = 427021005928
>>>
>>> number_bytes = number.to_bytes((number.bit_length() + 7) // 8, byteorder="big")  # Here's where the magic happens
>>> number_bytes, number_bytes.decode()
(b'cloth', 'cloth')
>>>
>>> encoded = base64.b64encode(number_bytes)
>>> encoded, encoded.decode()  # Don't let yourself tricked by the variable and method names resemblance
(b'Y2xvdGg=', 'Y2xvdGg=')
>>>
>>> # Now, getting the number back
...
>>> decoded = base64.b64decode(encoded)
>>> decoded
b'cloth'
>>>
>>> final_number0 = sum((item * 256 ** idx for idx, item in enumerate(reversed(decoded))))
>>> final_number0
427021005928
>>> number == final_number0
True
>>>
>>> # OR using from_bytes
...
>>> final_number1 = int.from_bytes(decoded, byteorder="big")
>>> final_number1
427021005928
>>> final_number1 == number
True

For more details on bitwise operations, check [SO]: Output of crc32b in PHP is not equal to Python (@CristiFati's answer).

CristiFati
  • 38,250
  • 9
  • 50
  • 87
2

Try this (https://docs.python.org/3/library/stdtypes.html#int.to_bytes)

>>> import base64
>>> x=427021005928
>>> y=x.to_bytes(5,byteorder='big').decode('utf-8')
>>> base64.b64encode(y.encode()).decode()
'Y2xvdGg='
>>> y
'cloth'
Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40
1

try

number = 427021005928

encode = base64.b64encode(bytes(number))

decode = base64.b64decode(encodeNumber)
0

The function below converts an unsigned 64 bit integer into base64 representation, and back again. This is particularly helpful for encoding database keys.

We first encode the integer into a byte array using little endian, and automatically remove any extra leading zeros. Then convert to base64, removing the unnecessary = sign. Note the flag url_safe which makes the solution non-base64 compliant, but works better with URLs.

def int_to_chars(number, url_safe = True):
    '''
    Convert an integer to base64. Used to turn IDs into short URL slugs.
    :param number:
    :param url_safe: base64 may contain "/" and "+", which do not play well
                     with URLS. Set to True to convert "/" to "-" and "+" to
                     "_". This no longer conforms to base64, but looks better
                     in URLS.
    :return:
    '''
    if number < 0:
        raise Exception("Cannot convert negative IDs.")
    # Encode the long, long as little endian.
    packed = struct.pack("<Q", number)
    # Remove leading zeros
    while len(packed) > 1 and packed[-1] == b'\x00':
        packed = packed[:-1]
    encoded = base64.b64encode(packed).split(b"=")[0]
    if url_safe:
        encoded = encoded.replace(b"/", b"-").replace(b"+", b".")
    return encoded

def chars_to_int(chars):
    '''Reverse of the above function. Will work regardless of whether
    url_safe was set to True or False.'''
    # Make sure the data is in binary type.
    if isinstance(chars, six.string_types):
        chars = chars.encode('utf8')
    # Do the reverse of the url_safe conversion above.
    chars = chars.replace(b"-", b"/").replace(b".", b"+")
    # First decode the base64, adding the required "=" padding.
    b64_pad_len = 4 - len(chars) % 4
    decoded = base64.b64decode(chars + b"="*b64_pad_len)
    # Now decode little endian with "0" padding, which are leading zeros.
    int64_pad_len = 8 - len(decoded)
    return struct.unpack("<Q", decoded + b'\x00' * int64_pad_len)[0]
speedplane
  • 15,673
  • 16
  • 86
  • 138
-1

You can do following conversions by using python

First of all import base64 by using following syntax

>>> import base64

For converting text to base64 do following

encoding

>>> base64.b64encode("cloth".encode()).decode()
    'Y2xvdGg='

decoding

>>> base64.b64decode("Y2xvdGg=".encode()).decode()
    'cloth'
Devang Padhiyar
  • 3,427
  • 2
  • 22
  • 42
  • This doesnt answer my question! I need to change 427021005928 into 'Y2xvdGg='. I do not have the value 'Y2xvdGg=' at the start – Moud Mar 26 '19 at 10:30