可以将SHA 256位哈希作为整数存储在BIGINT列中吗?
给定一个非常大的整数,比如:
>>> import hashlib
>>> h = hashlib.sha256("foo").hexdigest()
>>> h
'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'
>>> i = int(h, 16)
>>> i
19970150736239713706088444570146546354146685096673408908105596072151101138862L
我尝试在SQLite 3.7.13版本中创建一个表,像这样:
sqlite> .schema sha_table
CREATE TABLE "sha_table" (
"id" integer NOT NULL PRIMARY KEY,
"sha_hash" UNSIGNED BIG INT NOT NULL
);
sqlite> INSERT INTO `sha_table` (`sha_hash`) VALUES (19970150736239713706088444570146546354146685096673408908105596072151101138862);
sqlite> SELECT * FROM `sha_table`;
1|1.99701507362397e+76
把那个数字转换回预期的整数或十六进制格式并不成功:
>>> i = int(1.99701507362397e+76)
>>> i
19970150736239699946838208148745496378851447158029907897771645036831291998208L
>>> "{:0>64x}".format(i)
'2c26b46b68ffbe00000000000000000000000000000000000000000000000000'
编辑:从Python的sqlite3客户端尝试也似乎不行:
>>> cursor.execute("SELECT sha_hash FROM sha_table")
>>> i = int(cursor.fetchone()[0])
>>> i
19970150736239716016218650738648251798472370569655933119801582864759645011968L
>>>> "{:0>64x}".format(i)
'2c26b46b68ffbe00000000000000000000000000000000000000000000000000'
谢谢!
1 个回答
2
你有256位的数字,这个比BIGINT
能存的要大得多。
sqlite> CREATE TABLE "sha_table" (
...> "id" integer NOT NULL PRIMARY KEY,
...> "sha_hash" UNSIGNED BIG INT NOT NULL
...> );
sqlite> INSERT INTO sha_table (sha_hash) VALUES (9223372036854775807);
sqlite> INSERT INTO sha_table (sha_hash) VALUES (9223372036854775808);
sqlite> SELECT typeof(sha_hash) from sha_table;
integer
real
当你超出存储范围时,sqlite会把它当作REAL(也就是float
)来存储。
所以,回答你的问题,不可能在64位的数据类型中无损地存储一个256位的哈希值。你需要选择其他的数据类型来存储它,实际上可以选择文本类型或者BLOB类型。