-1

I found a somewhat related question but without an actual answer. How to increment a hex value in string format in python? So, I am going to ask: how do I increment the following 32-byte string by 1

the_string = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'

so that the_string takes on the values of...

the_string = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1'
the_string = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2'
the_string = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3'

in successive iterations. I tried...

    the_string = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1' + 1
TypeError: cannot concatenate 'str' and 'int' objects
DIVVS IVLIVS
  • 55
  • 2
  • 9
  • 4
    Are you coming from c? This seems like a hackish approach to cover some weird corner use-case. What are you trying to do? Why not simply using a nummeric variable? – Martin B. Sep 13 '17 at 09:56
  • Yes, I am coming from C. Does it show so clearly? :( – DIVVS IVLIVS Sep 13 '17 at 10:00
  • you want increase character at end of string.? – Anurag Misra Sep 13 '17 at 10:03
  • A piece of code in Python requires 32-byte (256-bit) unsigned integers and I thought of expressing them as a string. I should be able to iterate (theoretically, the range is actually huge) from \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 to \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 – DIVVS IVLIVS Sep 13 '17 at 10:07
  • 1
    C is low-level. You think in terms of bits that you put in your processor. Python is abstracted. You don't care about these things you care about the idea of your algorithm. And the execution is coincidentally on a computer that happens to use bits. But you don't think in this terms when using Python – Martin B. Sep 13 '17 at 10:08
  • Python supports arbitrarily large integers `2**256` will give you an integer, so why express them as bytestring? – MSeifert Sep 13 '17 at 10:08
  • For example, os.urandom(n) https://docs.python.org/2/library/os.html returns a string of n random bytes. I would like to be able to create the all 0s string and iterate from there. – DIVVS IVLIVS Sep 13 '17 at 10:09
  • What python version are you using? On python3 e.g. `i.to_bytes(32, 'big')` gives you a 32byte string for an integer `i` – mata Sep 13 '17 at 10:10
  • python command on the command line, I assume that means Python 2.7, right? – DIVVS IVLIVS Sep 13 '17 at 10:12
  • 2
    This seems to be an [X Y problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Please explain what the actual problem you are trying to solve is! – Klaus D. Sep 13 '17 at 10:14
  • @DIUUSIULIUS type "python --version" in your command line. But you can easily have Python3 alongside Python2 (that's the case for quite a few debian-based distros) – bruno desthuilliers Sep 13 '17 at 10:14
  • Yeah, thank you, it is Python 2.7.13. – DIVVS IVLIVS Sep 13 '17 at 10:17
  • Regarding the X Y problem. I need to initialize to \0 a variable that is composed conceptually by 256 bits, incrementing the 256-bit number by 1 at will, and being able to cast that variable to a string (in the sense of string expressed in https://docs.python.org/2/library/os.html for os.urandom(n) ). – DIVVS IVLIVS Sep 13 '17 at 10:21
  • i.to_bytes(32, 'big') AttributeError: 'int' object has no attribute 'to_bytes' But I had to try. ;) – DIVVS IVLIVS Sep 13 '17 at 10:24
  • Like I said, that's python3, in python2 you'd neet to use something like [this](https://stackoverflow.com/questions/16022556/has-python-3-to-bytes-been-back-ported-to-python-2-7)... – mata Sep 13 '17 at 10:40

2 Answers2

0

As the comments say, this is a strange thing to want to do. But here is one way to do it:

the_string = the_string[:-1] + chr(ord(the_string[-1]) + 1)

Python's strings are immutable, so you cannot just change one character--you need to create a new string then reassign the variable name to that new string. The code above splits the last character off the string, changes it to an integer, increments it, changes that to a character, then concatenates that new character to the original string with the old last character removed.

Note that if you print that new string it will not look exactly as you defined the first string. Your definition use octal codes for each character, but Python prints hex codes. So instead of a bunch of \0s you will get a bunch of \x00s.

Also note that this is an inefficient way to do whatever you are trying to do. Changing one string character requires you to copy the entire string. Python has other ways to do this kind of thing--have you looked into lists?

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50
  • Just to note: In Python2 - `chr(ord('\xff') + 1)` breaks... and even if it didn't the last byte should be `\x00` and the 2nd to last character should contain the relevant difference... – Jon Clements Sep 13 '17 at 10:42
0

I finally found a convoluted way. Fully based on this answer.

n = 0 #contains the integer representation of the string

while True:
    s = '%x' % n
    print s #0
    if len(s) & 1: #two hex per byte, so to avoid odd number of nibbles this check is needed
        s = '0' + s
        print s #00
    missing_len = 64 - len(s) #fill with leading \0x00 up to 256 bits, each nibble at a time
    for x in range(0, missing_len):
        s = '0' + s     
    the_string = s.decode('hex')
    print repr (s.decode('hex')) #'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    n = n + 1

Thank you for all your insightful comments! :)

DIVVS IVLIVS
  • 55
  • 2
  • 9