1

What is the fasted way to increment a bytes object in Python3.7? Consider the following:

>>> foo = '00000000000000000000000000000000'
>>> bar = binascii.unhexlify(foo)
>>> bar
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

I want to increment bar by 1, resulting in b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'.

If I try bar + 1, I get:

>>> bar + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat int to bytes

If I try bar + b'1', I get:

>>> bar + b'1'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001'

I know there must be a faster way to loop over the hexadecimal values than by going back to foo (a string), converting it to an int, incrementing it, converting back to a string, then doing binascii.unhexlify on it. But I'm not familiar with these bytes objects.

EDIT

The ultimate usage I'm aiming for is to loop over many values of plaintext below, while keeping KEY constant. I want to take plaintext from '0000000000000000000000000000000' to 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' and compute each value. I imagine it will take several years to complete, but I'm curious how fast it will go.

from Crypto.Cipher import AES
import binascii
KEY = binascii.unhexlify('AAAABBBBCCCCDDDDEEEEFFFF00001111')
plaintext = binascii.unhexlify('11112222333344445555666677778888')
rijn = AES.new(KEY, AES.MODE_ECB)
ciphertext = rijn.encrypt(plaintext)
binascii.hexlify(ciphertext).decode('utf-8')
4
  • Why do you want to do this? The best solution to your problem may lie at a higher level than this. Commented Nov 21, 2019 at 2:47
  • Thanks, I added the context in the edit Commented Nov 21, 2019 at 2:56
  • Several years is a severe underestimate. If you had started this computation at the beginning of the universe, it still wouldn't be a percent of a percent of a percent of the way done by now. Commented Nov 21, 2019 at 3:00
  • :) I'm still curious to see it in action Commented Nov 21, 2019 at 3:55

1 Answer 1

2

I'm curious too. Please post the full output of your program once it finishes running. lol...

You can move from integer to byte array in Python 3.2 using functions to_bytes and from_bytes. I think that's the missing piece in your little scheme.

So, bring in the data you want and then convert it to a number by interpreting it as a 'big-endian' number representation:

plaintext = binascii.unhexlify('11112222333344445555666677778888')
# also, we'll want to know our length later on
plaintext_length = len(plaintext)
plaintext_number = int.from_bytes(plaintext, 'big')

Now you can keep incrementing that number and then do with it as you wish. For instance, convert it back to a bytearray and / or print it out as hex:

plaintext_number += 1
new_plaintext = plaintext_number.to_bytes(plaintext_length, 'big')
new_hex = binascii.hexlify(new_plaintext)

print(f'Testing new string. This shouldnt take too long, almost done! {new_hex}')

new_ciphertext = rijn.encrypt(new_plaintext)
new_cipherhex = binascii.hexlify(new_ciphertext).decode('utf-8')

In summary: you can't increment a bytes array. You have to first interpret the bytes as something. We interpret it as a big-endian integer. Hang on to that integer and keep incrementing it. At each step, you can convert that integer back to a byte array or even back to a hex string if you like.

Sign up to request clarification or add additional context in comments.

1 Comment

@rusty-lemur - If this solution answered your question, please mark the answer as accepted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.