Twitter 生成D中的随机字母数字字符串

Twitter 生成D中的随机字母数字字符串,twitter,random,d,Twitter,Random,D,我正在寻找一种独立于平台的方法来为Twitter临时值生成随机字母数字字符串。目前我正在使用它,但它取决于/dev/random,这显然是特定于UNIX的: private auto _getNonce() { ubyte[32] buffer; File devRandom = File("/dev/random", "rb"); auto randomData = devRandom.rawRead(buffer); auto randomBase = Ba

我正在寻找一种独立于平台的方法来为Twitter临时值生成随机字母数字字符串。目前我正在使用它,但它取决于
/dev/random
,这显然是特定于UNIX的:

private auto _getNonce() {
    ubyte[32] buffer;
    File devRandom  = File("/dev/random", "rb");
    auto randomData = devRandom.rawRead(buffer);
    auto randomBase = Base64.encode(randomData);

    auto nonWords   = regex(r"[\W_]", "g");
    return replaceAll(randomBase, nonWords, "");
}
接下来是获取32字节的随机数据,base-64对它们进行编码,并去除所有非字母数字字符


nonce不需要加密安全,它只是用来防止重复提交。有什么建议可以在Windows和UNIX上更好地实现这一点吗?

std.random应该可以。如果您关心所使用的类型,它有多种随机数生成器,但是
std.random.rndGen
使用的是
Mt19937
,这是的一个实现。std.random的数字生成器是范围,这使得它们与火卫一的其他部分交互非常好

一种可能的实现方式

string genNonce()
{
    import std.algorithm, std.ascii, std.base64, std.conv, std.random, std.range;

    auto rndNums = rndGen().map!(a => cast(ubyte)a)().take(32);

    auto result = appender!string();
    Base64.encode(rndNums, result);

    return result.data.filter!isAlphaNum().to!string();
}

rndGen()
生成无限范围的随机数<代码>地图!(a=>cast(ubyte)a)(然后惰性地将它们转换为
ubyte
。并且
take(32)
延迟地获取其中的前32个,因此结果范围的长度是32而不是无穷大
Base64.encode
然后用于在输出范围内对其进行编码,然后对其进行过滤,使其仅包含字母数字字符,并转换为
字符串

注:经过这么多年,我应该指出,
randomCover
不会重复。这意味着此解决方案将只提供一个小写字符和一个大写字符。我研究了使用
cycle()
来解决这个问题,但是
randomCover
不支持无限范围

如果您只需要32个算术字符:

import std.algorithm : fill;
import std.ascii : letters, digits;
import std.conv : to;
import std.random : randomCover, rndGen;
import std.range : chain;
import std.stdio : writeln;

void main() {
    // dchar[] are random access, strings (char[]) are not
    auto asciiLetters = to!(dchar[])(letters);
    auto asciiDigits = to!(dchar[])(digits);

    dchar[32] key;
    fill(key[], randomCover(chain(asciiLetters, asciiDigits), rndGen));
    writeln(key);
}
特别声明

静态断言(!is窄带字符串!R);//窄字符串不能作为范围索引


窄字符串为char[]和wchar[]。虽然它们是数组,但在O(1)中找不到“字符”2531,这会阻止这些类型被视为随机访问,这是randomCover所要求的。

为什么不简单地使用std.random()模块???@DejanLekic寻找一个更完整的解决方案,它只会生成高达ulong的数字(我只能指望是32位的)。我需要一个字母数字字符串,我所能想到的所有方法都非常粗糙。你可以使用std.random,就像你在例子中所做的那样。Base64编码也在火卫一中…@DejanLekic我知道Base64编码在火卫一中,我在我的示例中使用它。:)是的,当我问苏霍辛为什么不使用std.random时,我就是这么想的…:)看起来他想要一些消息来源……;)像往常一样干得好,乔纳森@DejanLekic源代码始终是理想的,但是一个指向正确函数的指针就足够了。我不认为Dlang文档是最容易遵循的:p这个
a=>cast(ubyte)a
不是丢弃了生成的大部分随机位吗?我想a=>*演员阵容(ubyte[a.sizeof]*)和a
会更好,但它很难看。现在你有了一个ubyte[4]的范围,而phobos似乎没有一个函数来展平一个范围。@jpf除了为什么你会关心原始数字的大小之外?您使用的8位仍然是随机生成的。生成远远大于您使用的数字是正常的,典型的做法是使用
%
将值减小到您想要的范围。因此,您可以使用
cast(ubyte)(a%ubyte.max)
来代替,但是如果您关心的是
ubyte
中的所有数字,那么我认为这与仅使用cast没有任何区别。但是如果你真的想做的话,你可以像你建议的那样做。这里答案的关键部分实际上是使用std.random.Well,生成的随机数据超过必要数量可能会影响性能。但只要评测没有显示这是一个瓶颈,它可能就无关紧要了。你说的
char[]
不是随机访问是什么意思?我觉得这是不对的
string
是不可变的,但是
char[]
是可变的,如果这是你的意思的话?啊,你一直在谈论unicode字符。是的,有道理。