【发布时间】:2018-01-27 04:40:10
【问题描述】:
我有一个整数列表(员工 ID) 它们是 8 位长(虽然几乎都是从 00 开始,但它们实际上是 8 位长)
我需要为每个员工生成一个密钥:
- 5 chars including [A-Z][a-z][0-9]
- Must include 1 of [A-Z]
- Must include 1 of [0-9]
- Generated key must be unique
- If I know an employees ID I should not be able to determine their key
我需要生成一个算法来生成密钥,但我希望尽可能避免记录员工的密钥。越想越遇到问题。
如果我可以避免它,我不想生成所有密钥并将它们存储在某个地方 - 我宁愿它们是即时计算的
我可以在我的系统中隐藏一个秘密,除非你知道这个秘密,否则我可以使用它来确保密钥是不确定的。
我曾想过使用标准哈希算法(含盐),但目标空间的限制以及包括 1 A-Z 和 1 0-9 的限制似乎阻止了这一点。
我想我可以用一种方法来解决问题:
1. Build a deteremnistic function that maps integers starting from 1 [1, 2, 3, ...] to every possible result value
2. Map integers [1, 2, ...] to random other integers in the desired range [324, 43565, ...] in a way that preserves uniqueness (based on a secret salt which if changed would result in a different order).
这将保证唯一性,但第 1 步很棘手。结果集不连续,某些值可能缺少大写字母,而其他值可能缺少数字。
我可以通过使用 A1 开始每个代码来解决这个问题,这在技术上可行但将结果空间从 5 个字符减少到 3 个字符。
任何人都可以提出一些简单的方法来避免我必须记录所有生成的结果以进行唯一检查吗?
【问题讨论】:
-
密码编码部分:取[A-Z]的第一个字符,[0-9]的第二个字符,其余三个字符全集。这为您提供了 26*10*62*62*62 (= 61,965,280) 种可能性。这并没有完全覆盖 8 位数字,但很接近 - 所以你可能不需要改变 [A-Z] 和 [0-9] 的位置。通过一些数学运算,您可以在密码和 [0-61,965,279] 数字之间进行双向转换。
-
如果您确实需要覆盖整个 8 位范围,请将低于 50,000,000 的数字映射到 [AZ][0-9][?][?][?] 并将高于的数字映射到 [0- 9][AZ][?][?][?]。字符串模式不重叠。字符串生成和解析的决定很简单:低于 50,000,000 的数字与第一个字符是字母。
-
我很高兴我在这里发帖拉尔夫,答案是 1 号是要走的路。从员工 ID 到密钥的确定性、唯一性和基于秘密的映射函数有什么想法吗?
-
抱歉,对于第二部分并不是一个真正的想法。我很想说“加密”,但是您可以将(大致)27.6 位输入加密为 27.6 位输出,然后再解密结果吗?我不知道。也许如果你能保证 24 位(16 兆)内的数字,即 3 字节的文本。我不是加密专家。
标签: algorithm math random hash