简体   繁体   中英

Python hex digest to integer

Many online gambling games use a function that converts a hash into a decimal from 0-(usually 2^52).

Here's some code I grabbed that works fine, but I don't understand why it works:

def get_result(hash):
    hm = hmac.new(str.encode(hash),b'', hashlib.sha256) #hashing object

    h = hm.hexdigest() #hex digest, 32 bytes 256 bit
    print(h) #Something like 848ab848c6486d4f64
    c = int(h,16) 
    print(c) #numbers only, 77 numbers long...?
    if (c % 33 == 0): 
        return 1
    h = int(h[:13],16)
    return (((100 * E - h) / (E - h)) // 1) / 100.0

The part of the code that I don't understand is the conversion from h to c. h is a hex digest, so it is base-16. The python documentation says that the int(a,b) function converts the string a into a base-b integer. Here's my question:

  1. How can an integer number be base-16? Isn't the definition of decimal base-10 (0-9)? Where do the extra 6 come from?

  2. As far as I'm aware, a single hex digit can be stored by 4 bits, or 1/2 a byte. So a hex string of 64 length will occupy 32 bytes. Does this mean that any base of this data will also be 32 bytes? (converting the hex string to base-n, n being anything)

  3. What does the fact that the c variable is always 77 digits long mean?

How can an integer number be base-16? Where do the extra 6 come from?

This is known as the hexadecimal system .

Isn't the definition of decimal base-10 (0-9)?

Integer and decimal are not synonyms. You can have a integer in base 2 instead of base 10.

As far as I'm aware, a single hex digit can be stored by 4 bits, or 1/2 a byte. So a hex string of 64 length will occupy 32 bytes.

There are two different concepts: a hex string and a hex integer.

When you type in Python, for example, "8ff" , you're creating a hex string of length 3. A string is an array of characters. A character is (under the hood) a 1-byte integer. Therefore, you're storing 3 bytes ¹ (about your second statement, a hex string of length 64 will actually occupy 64 bytes).

Now, when you type in Python 0x8ff , you're creating a hex integer of 3 digits. If you print it, it'll show 2303, because of the conversion from base-16 (8ff, hex) to base-10 (2303, dec). A single integer stores 4 bytes², so you're storing 4 bytes .

Does this mean that any base of this data will also be 32 bytes? (converting the hex string to base-n, n being anything)

It depends, what type of data?

  • A string of length 3 will always occupy 3 bytes (let's ignore Unicode), it doesn't matter if its "8ff" or "123" .

  • A string of length 10 will always occupy 10 bytes, it doesn't matter if its "85d8afff" or "ef08c0e38e" .

  • An integer will always occupy 4 bytes³, it doesn't matter if its 10 or 1000000.

What does the fact that the c variable is always 77 digits long mean?

As @flakes noted , that's because 2^256 ~= 1.16e+77 in decimal.


¹ Actually a string of length 3 stores 4 bytes: three for its characters and one for the null terminator.

¹ Let's ignore that integers in Python are unbounded.

² If it's lesser than 2,147,483,647 (signed) or 4,294,967,295 (unsigned).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM