其他分享
首页 > 其他分享> > 生成(非常)大的非重复整数序列而无需预先混洗

生成(非常)大的非重复整数序列而无需预先混洗

作者:互联网

背景

我有一个简单的媒体客户端/服务器我写了,我想生成一个非显而易见的时间值,我发送每个命令从客户端到服务器.时间戳将包含相当多的数据(纳秒级分辨率,即使由于现代操作系统中定时器采样的限制而不能真正准确),等等.

我想要做的(在Linux上,在C中),是生成一对一的n位值序列(假设数据存储在128位int-int-int-int元素中),没有重叠/碰撞值.然后,我将伪随机的128位值/数字作为“盐”,将其应用于时间戳,然后开始向服务器发送命令,增加预先盐化/预先散列的值.

时间戳大小如此之大的原因是时间戳可能必须适应非常大的持续时间.

我怎么能用初始盐值完成这样的序列(非碰撞)? The best approach that sounds along the lines of my goal is from this post, which notes

If option 1 isn’t “random” enough for you, use the CRC-32 hash of said
global (32-bit) counter. There is a 1-to-1 mapping (bijection) between
N-bit integers and their CRC-N so uniqueness will still be guaranteed.

但是,我不知道:

>如果可以(有效地)扩展到128位数据.
>如果通过某种类型的加法/乘法 – 盐值来提供序列的初始种子会破坏它或引入冲突.

跟进

我意识到我可以使用libssl中的128位随机散列或类似的东西,但我希望使用相同的salt值的远程服务器能够将散列的时间戳转换回它们的真值.

谢谢.

解决方法:

您可以使用线性同余生成器.利用正确的参数,保证产生具有完整周期(即没有碰撞)的非重复序列[唯一]序列.

这是随机(3)在TYPE_0模式下使用的.我将它改编为完整的unsigned int范围,种子可以是任何unsigned int(参见下面的示例代码).

我相信它可以扩展到64或128位.我看一下:https://en.wikipedia.org/wiki/Linear_congruential_generator,看看参数的限制,以防止碰撞和良好的随机性.

遵循维基页面指南,您可以生成一个可以将任何128位值作为种子的指令,并且在生成所有可能的128位数之前不会重复.

您可能需要编写一个程序来生成合适的参数对,然后测试它们的“最佳”随机性.这将是一次性操作.

获得它们后,只需将这些参数插入实际应用中的等式中即可.

这是我在寻找类似东西时一直在玩的一些我的代码:

// _prngstd -- get random number
static inline u32
_prngstd(prng_p prng)
{
    long rhs;
    u32 lhs;

    // NOTE: random is faster and has a _long_ period, but it _only_ produces
    // positive integers but jrand48 produces positive _and_ negative
#if 0
    rhs = jrand48(btc->btc_seed);
    lhs = rhs;
#endif

    // this has collisions
#if 0
    rhs = rand();
    PRNG_FLIP;
#endif

    // this has collisions because it defaults to TYPE_3
#if 0
    rhs = random();
    PRNG_FLIP;
#endif

    // this is random in TYPE_0 (linear congruential) mode
#if 0
    prng->prng_state = ((prng->prng_state * 1103515245) + 12345) & 0x7fffffff;
    rhs = prng->prng_state;
    PRNG_FLIP;
#endif

    // this is random in TYPE_0 (linear congruential) mode with the mask
    // removed to get full range numbers
    // this does _not_ produce overlaps
#if 1
    prng->prng_state = ((prng->prng_state * 1103515245) + 12345);
    rhs = prng->prng_state;
    lhs = rhs;
#endif

    return lhs;
}

标签:c-3,random,linux,uniqueidentifier,hash
来源: https://codeday.me/bug/20190611/1219033.html