在Swift中生成String的自定义长度哈希值

时间:2018-05-15 12:38:13

标签: ios swift hash

有可能以某种方式"哈希"一个给定的字符串,长度为n,哈希值为任意长度m? 我希望实现以下目标:

let s1 = "<UNIQUE_USER_IDENTIFIER_1>" 
let s2 = "<UNIQUE_USER_IDENTIFIER_2>"

let x1 = s1.hashValue(length: 4) 
let x2 = s2.hashValue(length: 4) 

我想为每个给定用户分配一个(例如四位数)数字,该数字基于其唯一的UID。这可能吗?

1 个答案:

答案 0 :(得分:1)

首先,我想清楚你的意思是&#34;哈希&#34;并不是指(无损)压缩。&#34;你应该期待一些碰撞,其中x1和x2对于不同的s1和s2是相同的值。如果你真的是指一个映射,以便没有碰撞,那么我们必须更多地了解这个问题。在一般情况下不可能实现这一点(参见Pigeonhole principle)。但是在输入中有足够冗余的特殊情况下可以实现。或者可以通过维护表(即数据库等)来完成。这个答案的其余部分是关于散列的。

如果您的UID是在iOS(或任何v4 UUID)上创建的UUID,那么它的位已经非常高质量,并且最后四位应该没有任何散列。中间有几个字节你应该避免,但整个结尾部分是随机的,所以理想的哈希值。

如果您的UUID不是随机的,您可以尝试使用默认哈希值并从中提取所需的位数,但非加密哈希值在它们的位之间始终没有良好的独立性,因此可能会发生碰撞比你更喜欢。

在这种情况下,使用大于所需大小的加密哈希并截断它(或取最低有效位;任一组都可以)。这通常在加密中完成。例如,SHA-512/256是一种常用的散列,它计算512位散列并从中提取256位。密码散列需要所有位的高度独立性,因此任何位子集也都是抗冲突的。

BTW,如果你的意思是&#34; 4位小数,&#34;然后你应该期望碰撞大约1次100。如果你的意思是16位(4个十六进制数字),你应该预计在300中发生一次碰撞。这些是你最好的情况并且意味着你的哈希工作得很好。请参阅Birthday Attack以获取期望表和一些有用的近似值。