我想生成随机1M(出现)独特的字母数字键,并将它们存储在数据库中。 每个键将是8个字符并且仅所述子集“ABCDEFGHIJKÑpqrstuvxyz和0-9”将被使用。
字母L,M,O和w抛弃。 “m和W”被排除,因为有限的印刷空间,因为每个键将在产品中非常小的空间被打印。 删除M值和W能够增加字母大小与2点,提高了可读性。 升和邻滴入,因为它们很容易用1混合起来,i和0在当前的打印尺寸。 我们做了一些测试字符1,i和0总是正确读取,L和O不得不多次失误。 首都被冷落出于同样的原因为“M和W”。
那么,为什么不是一个序列? 有几个原因:该键可以事后登记,我们不希望任何人猜测序列中的下一个关键和注册别人的钥匙。 外观:我们不需要客户和竞争要知道,我们只运了几千项。
有没有生成密钥,确保每一个键的唯一性,并将它们存储在数据库中的实际的方法? 谢谢!
编辑:@CodeInChaos指出一个问题: System.Random
不是很安全,并且序列可以毫无困难地大量复制。 我把它换成Random
在这里安全的发电机:
var possibilities = "abcdefghijknpqrstuvxyz0123456789".ToCharArray();
int goal = 1000000;
int codeLength = 8;
var codes = new HashSet<string>();
var random = new RNGCryptoServiceProvider();
while (codes.Count < goal)
{
var newCode = new char[codeLength];
for (int i = 0; i < codeLength; i++)
newCode[i] = possibilities[random.Next(possibilities.Length)];
codes.Add(new string(newCode));
}
// now write codes to database
static class Extensions
{
public static byte Next(this RNGCryptoServiceProvider provider, byte maximum)
{
var b = new byte[1];
while (true)
{
provider.GetBytes(b);
if (b[0] < maximum)
return b[0];
}
}
}
(Next方法不是非常快,但可能是很好的满足你的目的)
百万是没有太大的这些天,你也许可以做到一台机器上相当迅速。 这是一个一次性的手术后所有。
- 以一个哈希表(或HashSet的)
- 生成随机密钥,并把它们放到它作为键(或直接,如果一组),直到计数为100万
- 把它们写到数据库
我的快速和肮脏的测试代码是这样的:
function new-key {-join'abcdefghijknpqrstuvxyz0123456789'[(0..7|%{random 32})]}
$keys = @{}
for(){$keys[(new-key)]=1}
但是PowerShell是缓慢的 ,所以我希望C ++或C#做的非常好这里。
有没有生成密钥,确保每一个键的唯一性,并将它们存储在数据库中的实际的方法?
因为这是一个单一的操作,你可以简单地做到以下几点:
1)生成一个密钥
2)验证所生成的键不存在于数据库中。
3)如果确实存在生成新的密钥。
3B),如果它不存在,写入数据库4)返回步骤1
当然也有其他的选择,在它归结为生成密钥,并确保它不存在于数据库中结束。
理论上你可以产生10个百万个密钥(为了节省处理能力),并写入文件。 一旦密钥生成只是看每个人,看看它是否已经在数据库中退出。 你可能会编程工具,做这个,在不到48小时。
我遇到了类似的问题,一旦..我所做的就是创建一个唯一的序列YYYY / MM / DD / HH / MM / SS /米利斯/ nano和获得它的哈希码。 从那以后,我使用哈希作为重点。 你的客户和你的竞争对手将无法猜测下一个值。 它可能不是充分证明但对我来说这已经足够了!
要真正得到随机字符串,你可以使用类似下面的代码:
Random rand = new Random(new DateTime().Millisecond);
String[] possibilities = {"a","b","c","d","e","f","g","h","i","j","k",
"l","n","p","q","r","s","t","u","v","x","y","z","0","1","2","3","4",
"5","6","7","8","9"};
for (int i = 0; i < 1000000; ++i)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int j = 0; j < 8; ++j)
{
sb.Append(possibilities[rand.Next(possibilities.Length)]);
}
if (!databaseContains(sb.ToString()))
databaseAdd(sb.ToString());
else
--i;
}