如果您在计算机上使用SHA-256对字符串进行哈希处理,而在计算机上使用SHA-256对相同字符串进行哈希处理,我们将生成相同的值吗?算法是否依赖于种子(所以我们俩都需要相同的种子)还是其他一些这样的参数?

edit:
为澄清起见,“字符串”是指“相同”字节输入”(作为注释和@ispiro的答案指出),对于同一字符串,可能会有所不同,具体取决于编码。

评论

您必须小心“字符串”的含义。字符串是字符序列,而哈希函数通常处理字节序列。如果使用不同的编码将字符串映射到字节序列,则可以为您提供不同的哈希值。

不,这取决于编码。所选答案具有误导性。也许看看这个:stackoverflow.com/questions/47963143/…

同样,尽管纯哈希函数中没有“种子”(又名“盐”),但某些库将盐的生成作为函数称为“哈希”(尽管严格来说,哈希是您已经整合了输入和盐,并完成了编码)。因此,如果您谈论的是纯哈希,那么可接受的答案是正确的,但是如果其他读者认为他们的库“哈希”函数仅对输入字符串进行哈希处理,则可能会误导读者。

甚至事实并非不是没有编码的字节串,如果字符串“看起来相同”,甚至可以比较相同,那么还有各种各样的字符看起来相同,不可打印或零宽度。

OP可以确认,但我认为问题是假设相同的字节序列,并询问有关在相同输入下算法的行为的更多信息。

#1 楼

是的,如果使用相同的函数对相同的输入进行哈希处理,则始终会得到相同的结果。

这是因为它是哈希函数。根据定义,函数是一组输入和一组允许的输出之间的关系,其属性是每个输入都与一个输出正好相关。

实际上,评估哈希值不涉及任何种子。函数。

现在,这就是事物在实践中的工作方式。
在事物的理论方面,我们经常谈论哈希函数族。在那种情况下,确实存在一个密钥,可以选择我们正在使用的家庭成员。造成这种情况的原因是有关抗冲突性定义的技术问题。

单个哈希函数$ H的抗冲突性的简单定义:\ {0,1 \} ^ * \ to \ { 0,1 \} ^ n $对于所有有效算法$ \ mathcal {A} $而言,以下几率可以忽略不计$$ \ Pr [(x_1,x_2)\ gets \ mathcal {A}(1 ^ n): H(x_1)= H(x_2)] $$

问题是无法实现。假设$ H $正在压缩,则必然存在冲突。因此,仅对冲突中的一个进行硬编码并输出的算法$ \ mathcal {A} $具有
$$ \ Pr [(x_1,x_2)\ gets \ mathcal {A}(1 ^ n): H(x_1)= H(x_2)] = 1。$$
因此无法实现该定义,因为即使没有人知道它是什么,根据定义,该$ \ mathcal {A} $也存在。

为解决此问题,我们为一系列哈希函数$ \ {H_k:\ {0,1 \} ^ * \ to \ {0,1 \} ^ n \} _ k $定义了抗碰撞性。
如果这样的家庭认为以下概率可以忽略,则定义该家庭具有抗碰撞性
$$ \ Pr_ {k \ gets \ {0,1 \} ^ n} [(x_1, x_2)\ gets \ mathcal {A}(k):H_k(x_1)= H_k(x_2)]。$$

在这里,我们不会遇到相同的问题,因为需要从一个指数较大的族中随机选择统一选择的确切函数$ \ mathcal {A} $。由于$ \ mathcal {A} $最多可能对族中的多项式函数具有硬编码的冲突,因此这种散列函数族并非易事。

请注意,这意味着在某种程度上散列函数的理论处理与其实际使用之间的脱节。

评论


$ \ begingroup $
您能告诉我在哪里可以阅读这些公式的语法?
$ \ endgroup $
– SwiftsNamesake
18年2月5日在16:43

$ \ begingroup $
@SwiftsNamesake您是否介意对哪些部分感到困惑?
$ \ endgroup $
– Maeher
18年2月5日在16:46

$ \ begingroup $
我只是对如何解释这些表达感到好奇。但是,它们使我想起了一些列表理解。
$ \ endgroup $
– SwiftsNamesake
18年2月5日在17:06

$ \ begingroup $
@SwiftsNamesake:$ 1 ^ n $表示(这里)位于$ 1处的$ n $位的位串。它属于$ \ {0,1 \} ^ n $,完全是$ n $位位串的集合。 ,具有$ 2 ^ n $个元素(这是一个数字!)。 $ \ {0,1 \} ^ * $原则上是所有(无限但无限制长度)位串的(无限)集合,尽管在实践中通常最终是所有位串的(无限但有限)集合少于$ 2 ^ {64} $或$ 2 ^ {128} $位。 $ \ displaystyle \ Pr_ {k \ gets \ {0,1 \} ^ n} [\ operatorname {foo}(k)] $是$ \ operatorname {foo}(k)$持有统一随机$的概率k $位比特串。
$ \ endgroup $
–fgrieu♦
18-2-5在17:46

$ \ begingroup $
@SwiftsNamesake:$ \ {H_k:\ {0,1 \} ^ * \ to \ {0,1 \} ^ n \} _ k $是$ \ {0,1 \}中的一组函数由$ k $参数化的^ * $到$ \ {0,1 \} ^ n $,每个记为$ H_k $。并且$ \ displaystyle \ Pr_ {k \ gets \ {0,1 \} ^ n} [(x_1,x_2)\ gets \ mathcal {A}(k):H_k(x_1)= H_k(x_2)] $是对于均匀一致的$ k $位比特串,算法$ \ mathcal {A} $在输入$ k $作为输入时,输出一对(隐式:不同的)比特串,使得散列成员$ H_k $的概率家庭碰撞这些比特串。
$ \ endgroup $
–fgrieu♦
18年2月5日在18:05

#2 楼

字符串不是字节数组。

公认的答案涉及SHA256是否包含种子的问题。 (尽管“功能”一词的证明是有争议的,因为我们将密码到键功能称为“功能”,尽管它们可以包含“盐和胡椒”。)但是字符串仍需要编码为字节以进行散列。 br />
通过仔细研究Drunix的评论,发现由于字符串以不同的编码方式编码,相同的字符串很可能返回不同的哈希值。

这是一个极高的评价有关StackOverflow的答案,建议使用UTF8或UTF16(答案中的“ unicode”),它们名义上将返回不同的字节,因此也将返回不同的哈希值。

这是使用ASCII的答案。哪个“使用替换后备替换以问号(“?”)字符替换它不能编码的每个字符串和不能解码的每个字节。” (MSDN)再次返回与UTF8编码的字符串不同的哈希值。

另外,在StackOverflow上采用以下答案。它提到了macOS(Apple的Mac操作系统)如何以特定的(意外的)方式存储文件名,以便某些字符串将“改变”(至少以字节表示)。

当然,如果您的字符串来自文本文件,则取决于文件的编码。记事本默认(至少在我的计算机上)默认为ANSI。

评论


$ \ begingroup $
为什么您也没有提到EBCDIC?或具有非8位字节的计算机;)
$ \ endgroup $
–哈根·冯·埃森(Hagen von Eitzen)
18-2-5在20:58



$ \ begingroup $
@HagenvonEitzen我想去学习象形文字,但感觉不合格:)但是,认真地说,我的意思是指出可能的问题。
$ \ endgroup $
– ispiro
18-2-5在21:03

$ \ begingroup $
@HagenvonEitzen我实际上在6位IBM 1401大型机上实现了SHA-256,以便可以挖掘比特币。不幸的是,以每哈希80秒的速度,这台1960年代的打孔卡商务计算机要比开采整个区块的生命多得多,因此它并不具有成本效益。
$ \ endgroup $
– Ken Shirriff
18年2月5日在22:09

$ \ begingroup $
我已经编辑了我的问题,以解决您的观点和意见。 @Maeher正确解释了我的问题。
$ \ endgroup $
– conor
18年2月6日,0:06

$ \ begingroup $
该答案与尝试纠正的错误基本相同。现实情况是,“字符串”一词含糊不清:它通常是指字节序列(通常是八位字节),偶尔是指字符序列(例如Unicode字符),经常是指近似于字符序列的东西(例如16位的无符号整数,旨在解释为UTF-16代码单元,有时不止一个(例如,当唯一可用的字符编码是单字节编码时)。
$ \ endgroup $
–ruakh
18年2月6日在8:22