首页 > 解决方案 > Python十六进制摘要到整数

问题描述

许多在线赌博游戏使用将哈希从 0-(通常为 2^52)转换为小数的函数。

这是我抓取的一些可以正常工作的代码,但我不明白它为什么有效:

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

我不明白的部分代码是从h到c的转换。h 是十六进制摘要,因此它是 base-16。python 文档说 int(a,b) 函数将字符串 a 转换为 base-b 整数。这是我的问题:

  1. 整数如何以 16 为基数?十进制base-10(0-9)的定义不是吗?额外的 6 个从哪里来?

  2. 据我所知,一个十六进制数字可以存储 4 位或 1/2 个字节。所以一个长度为 64 的十六进制字符串将占用 32 个字节。这是否意味着此数据的任何基数也将是 32 字节?(将十六进制字符串转换为 base-n,n 是任何东西)

  3. c 变量总是 77 位长这一事实是什么意思?

标签: pythonhex

解决方案


整数如何以 16 为基数?额外的 6 个从哪里来?

这被称为十六进制系统

十进制base-10(0-9)的定义不是吗?

整数和小数不是同义词。你可以有一个以 2 为底的整数,而不是以 10 为底的整数。

据我所知,一个十六进制数字可以存储 4 位或 1/2 个字节。所以一个长度为 64 的十六进制字符串将占用 32 个字节。

有两个不同的概念:十六进制字符串和十六进制整数。

例如,当您在 Python 中键入时"8ff",您正在创建一个长度为 3 的十六进制字符串。字符串是一个字符数组。一个字符(在底层)是一个 1 字节的整数。因此,您要存储3 个字节¹(关于您的第二条语句,长度为 64 的十六进制字符串实际上将占用 64 个字节)。

现在,当您输入 Python 时0x8ff,您将创建一个 3 位的十六进制整数。如果您打印它,它将显示 2303,因为从 base-16(8ff,hex)到 base-10(2303,dec)的转换。单个整数存储 4 个字节²,因此您存储4 个字节

这是否意味着此数据的任何基数也将是 32 字节?(将十六进制字符串转换为 base-n,n 是任何东西)

这取决于,什么类型的数据?

  • 长度为 3 的字符串将始终占用 3 个字节(让我们忽略 Unicode),不管它是"8ff"还是"123".

  • 长度为 10 的字符串将始终占用 10 个字节,不管它是"85d8afff"还是"ef08c0e38e".

  • 一个整数总是占用 4 个字节³,不管它是 10 还是 1000000。

c 变量总是 77 位长这一事实是什么意思?

正如@flakes 所指出的,那是因为 2^256 ~= 1.16e+77 十进制。


¹ 实际上,长度为 3 的字符串存储 4 个字节:三个用于其字符,一个用于空终止符。

¹ 让我们忽略 Python 中的整数是无界的。

² 如果小于 2,147,483,647(有符号)或 4,294,967,295(无符号)。


推荐阅读