Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为Swift生成十进制输出的哈希_Swift_Cryptography - Fatal编程技术网

为Swift生成十进制输出的哈希

为Swift生成十进制输出的哈希,swift,cryptography,Swift,Cryptography,我想将一个字符串散列到一个散列对象中,该对象具有一些数值NSNumber/Int作为输出,而不是字母数字值 问题是,在通过swift和一些第三方库进行挖掘之后,我无法找到任何满足我们需要的库 我正在开发一个聊天SDK,它使用NSNumber/Int作为唯一标识符来关联聊天消息和对话消息 我公司的要求是不在数据库中存储任何附加字段 或者改变我们现有的模式,使事情复杂化 我的团队提供的一个简洁的解决方案是某种生成数字的散列函数 func userIdToConversationNumber(id:S

我想将一个
字符串
散列到一个散列对象中,该对象具有一些数值
NSNumber
/
Int
作为输出,而不是字母数字值

问题是,在通过swift和一些第三方库进行挖掘之后,我无法找到任何满足我们需要的库

我正在开发一个聊天SDK,它使用
NSNumber
/
Int
作为唯一标识符来关联聊天消息和对话消息

我公司的要求是不在数据库中存储任何附加字段 或者改变我们现有的模式,使事情复杂化

我的团队提供的一个简洁的解决方案是某种生成数字的散列函数

func userIdToConversationNumber(id:String) -> NSNumber

我们可以使用该函数将
String
转换为
NSNumber
/
Int
。这个
Int
应该由这个函数产生,碰撞的概率应该可以忽略不计。任何方法的任何建议。

是的,您可以使用加密哈希函数创建抗冲突的哈希。如果遵循算法规范,则此类哈希函数的输出以位为单位。然而,实现通常只返回字节或字节值的编码。散列不会返回数字,正如其他散列在注释中指出的那样

将这样的散列转换为32位的数字相对容易,例如
Int
Int32
。您只需获取散列中最左边的字节,并将其解释为无符号整数

然而,加密哈希具有相对较大的输出大小,以确保冲突的可能性较小。碰撞容易出现生日问题,这意味着您只需尝试将hLen的2次方除以2个输入,即可在生成的集合中创建碰撞。例如,您需要2^80次尝试创建RIPEMD-160哈希的冲突

现在对于大多数加密散列,当然是普通散列,同样的规则也适用。这意味着对于32位散列,您只需要2^16个散列就可以合理地确定是否存在冲突。这不好,65536次尝试很容易完成。有些人可能会很幸运,例如,在256次尝试后,发生碰撞的几率为256分之一。那不好


因此,计算一个散列值以将其用作ID是可以的,但您需要散列函数的完整输出,例如256位的SHA-2,以确保不会发生冲突。否则,您可能需要使用序列号。

您需要执行的关键计算是生日限制。我最喜欢的表是中的表,当我设计像这样的系统时,我经常引用它

该表表示在发生冲突之前,对于给定的哈希大小,可以哈希多少项。这是基于一个完全一致的散列,加密散列是它的近似值

因此,对于一个64位整数,在散列了6M个元素之后,该列表中的任何地方都有百万分之一的可能发生冲突。对2000万个元素进行散列后,有千分之一的可能发生单一冲突。在50亿个元素之后,你应该赌一次碰撞(50%的几率)

因此,这一切都取决于您计划散列多少个元素,以及如果发生冲突(是否会造成安全问题?您能检测到它吗?您能做些什么,比如更改输入数据吗?),以及您愿意为给定问题承担多大风险

就我个人而言,在这些方面我是百万分之一的人,尽管我被说服有时会降到千分之一。(同样,这不是任何给定元素发生冲突的1:1000机会;那将是可怕的。这是在散列一些元素之后发生冲突的1:1000机会。)在攻击者可以制作任意内容(任意大小)供您散列的情况下,我不会接受百万分之一。但对于长度受限的结构化数据(电子邮件地址、URL),我非常熟悉它

如果这些数字适合您,那么您需要的是一个所有位高度一致的散列。这是一个SHA杂烩。我会使用SHA-2(比如SHA-256),因为你应该一直使用SHA-2,除非你有充分的理由不这样做。由于SHA-2的位都是相互独立的(或者至少这是它的意图)。因此,您计算一个SHA-256,并将顶部()64位作为一个整数,这就是您的哈希

作为一项规则,对于中等大小的东西,您可以在64位中使用它。您无法在32位中摆脱此问题。所以当你说“NSNumber/Int”时,我希望你明确地表示“64位整数”。例如,在32位平台上,Swift的Int只有32位,所以我会使用UInt64或UInt64_t,而不是Int或NSInteger。我建议在这里使用无符号整数,因为它们是真正唯一的位模式,而不是“数字”(也就是说,将它们相加或相乘是没有意义的),并且具有负值在标识符中往往容易混淆,除非它具有某种语义意义

注意,这里所说的关于散列的一切对于随机数也是正确的,如果它们是由加密随机数生成器生成的。事实上,我通常用随机数来解决这类问题。例如,如果我希望客户端为消息生成自己的随机唯一ID,我需要多少位来安全地避免冲突?(在我的许多系统中,可能无法使用值中的所有位;有些位可能用作标志。)

这是我的一般解决方案,但如果您的输入空间受到限制,还有更好的解决方案。如果输入空间小于2^64,则根本不需要哈希。显然,任何最多8个字符的拉丁-1字符串都可以存储在64位值中。但是,如果您的输入更加受限,那么您可以压缩数据并获得稍长的时间