从C#中的整数列表中,我需要生成一个唯一值列表。我认为在MD5或类似的东西,但它们产生太多字节。
整数大小为2个字节。
我希望获得单向通信,例如
0 -> ARY812Q3
1 -> S6321Q66
2 -> 13TZ79K2
因此,证明散列,用户无法知道整数或干扰散列列表后面的序列。
现在,我尝试使用MD5(我的号码),然后我使用了前8个字符。但是我在51389发现了第一次碰撞。我可以使用哪些其他替代方案?
正如我所说,我只需要一种方式。没有必要能够从散列中计算整数。系统使用字典来查找它们。
更新:
回复有关使用GetHashCode()的一些建议。 GetHashCode返回相同的整数。我的目的是向最终用户隐藏整数。在这种情况下,整数是数据库的主键。我不想将此信息提供给用户,因为他们可以按周推断数据库中的记录数或记录增量。
哈希不是唯一的,所以也许我需要像TripleDes那样使用加密,但我想快速而简单地使用。此外,TripleDes也会返回太多字节。
更新2: 我在谈论哈希,这是一个错误。实际上,我试图模糊它,我尝试使用哈希算法,这不是一个好主意,因为它们不是唯一的。
答案 0 :(得分:4)
随意使用(或修改)我开发的库,可以通过Nuget安装:
Install-Package Kent.Cryptography.Obfuscation
这会将非负的ID(例如127)转换为 8个字符的字符串,例如 xVrAndNb ,然后返回(有一些可用的选项可以在每次生成序列时随机化序列。)
使用示例
var obfuscator = new Obfuscator();
string maskedID = obfuscator.Obfuscate(15);
完整文档位于:Github。
我遇到了这个问题,我无法在StackOverflow中找到我想要的东西。所以我创建了这个混淆类,并在github上分享了它。
您可以通过以下方式使用它:
Obfuscation obfuscation = new Obfuscation();
string maskedValue = obfuscation.Obfuscate(5);
int? value = obfuscation.DeObfuscate(maskedValue);
也许这对未来的访客有帮助:)。
答案 1 :(得分:2)
使用Skip32加密,产生32位输出。我找到了this C# implementation,但无法保证其正确性。 Skip32是一种相对不常见的加密选择,可能还没有得到很多分析。仍然应该足以满足你的混淆目的。
强有力的选择是在FFX模式下使用AES格式保留加密。但这非常复杂,可能对你的应用程序来说太过分了。
使用Base32(不区分大小写,字母数字)编码时,32位值对应7个字符。以十六进制编码时,它对应于8个字符。
还有一种非加密替代方法,即生成随机值,将其存储在数据库中并处理冲突。
答案 2 :(得分:0)
对于你想要的,我建议使用GUID
(或其他类型的唯一标识符,其中碰撞概率最小或没有)并将它们存储在数据库行中,然后再从不向用户显示ID
。
恕我直言,将数据库中的主键显示给用户是一种不好的做法(更不用说让用户对它们进行任何操作了。)
如果他们需要因某种原因拥有对数据库的原始访问权限,那么就不要使用ints作为主键,并将它们guid
设为id
s要求失去重要性,因为他们只能访问记录的数量)
根据您的要求,如果您不在乎该算法的计算成本可能很高,那么每次添加新行时您只需生成一个随机的8字节字符串,并保持生成随机字符串,直到您找到一个那个数据库中尚未存在。
这远非最优,而且可能计算成本很高,但是你使用16位{{1}}并且最大行数是65536,我对此并不在意太多(8字节随机字符串在65536可能性列表中的可能性是最小的,所以如果你的伪随机生成器很好的话,你可能在第一次或第二次尝试时都很好。)
答案 3 :(得分:0)
Xor整数。也许使用随机密钥,它是每个用户生成的(存储在会话中)。虽然它不是严格的哈希(因为它是可逆的),但优点是您不需要将它存储在任何地方,并且大小将是相同的。