Scala 每次为给定数字生成相同的随机唯一数

Scala 每次为给定数字生成相同的随机唯一数,scala,random,mapping,random-seed,Scala,Random,Mapping,Random Seed,我们有一组,每个组都有数十亿条记录。每个组将由一个id唯一标识,组中的每个记录将由一个id唯一标识。通过组合这两个id(concat(groupid,recordid)),我们可以跨组标识一个记录 现在我们正在尝试更改这些id(串联)值,在我们的报告中,我们不希望与我们维护的客户共享直接id,而是希望将id转换为其他唯一id并与客户共享,这样他们就很难识别组 我们已经尝试为此生成哈希(hmac256哈希)值,但这对我们的客户不起作用,因为这大大增加了他们的存储空间。如果当前id的长度为20位,并

我们有一组,每个组都有数十亿条记录。每个组将由一个id唯一标识,组中的每个记录将由一个id唯一标识。通过组合这两个id(concat(groupid,recordid)),我们可以跨组标识一个记录

现在我们正在尝试更改这些id(串联)值,在我们的报告中,我们不希望与我们维护的客户共享直接id,而是希望将id转换为其他唯一id并与客户共享,这样他们就很难识别组

我们已经尝试为此生成哈希(hmac256哈希)值,但这对我们的客户不起作用,因为这大大增加了他们的存储空间。如果当前id的长度为20位,并且生成45个字符的哈希不起作用。因此,在生成20位/字符串或至少25位/字符串唯一值时,寻找一个更好的选项,该值不会发生冲突

正在寻找关于此的一些输入

我们已经尝试为此生成哈希(hmac256哈希)值,但这对我们的客户不起作用,因为这大大增加了他们的存储空间。如果当前id的长度为20位,并且生成45个字符的哈希不起作用

例如: groupId=910612349078 recordId=6234091234

对于上述两个值,系统今天生成的唯一id如下所示: uniqueId=9106123490786234091234(concat(groupId,recordId))

唯一id的预期行为将是一些随机/哈希值:
newUniqueId=some hash或some random number

我会尝试使用合适的快速安全哈希函数-

ChaCha20产生每个64字节的伪随机块,这些伪随机块与要加密或解密的数据异或。它需要256位密钥和64位nonce。假设您的所有Id都符合64位(毕竟,20位数字非常接近264-1,即18446744073709551615),设置您的密钥,使用组Id作为nonce,并加密记录Id XORing ChaCha20输出

您没有提到平台,所以没有代码,但是在C/C++/Go/Rust/…中有很多很好的实现

更新

您可以尝试在计数器模式下使用ChaCha20作为分组密码。然后输入键,64位组id作为nonce,64位记录id作为计数器。输出将是您发送给客户的64位块

好的,我使用了Monocypher实现(ChaCha20页面底部的链接),并将其用作上面建议的分组密码。到目前为止,我觉得很好——不同的groupId/recordId产生了截然不同的加扰值。代码是在C++中,用LLVM 8和MSVC++ 19.2编译。我把整个项目放在Github上

更新二

抱歉,我的输入错误可能误导了您(当块的大小为64字节时,将其声明为64位,现在更正)


是的,块大小是64字节(实际上是32位的16个uint32字节)。ChaCha20能够产生264个这样的块。所以你可以让你的输入大小为12字节,而输出则是块的前12字节。请检查回购协议中的更新代码。我已经反转打印了12字节块,以显示它与以前一样(endianness)。您可以将任何加扰大小设置为64。

您可以澄清组ID和记录ID的大小吗?它们适合64位空间吗?
concat(129,87)
是否会产生与
concat(12987)
不同的结果?这是一个很好的观点,但当我们创建组id时,我们确保组id不会发生子字符串冲突。组id生成本身就是处理这些情况的工作。所以我们永远不会有这个问题。谢谢分享这些信息,让我回来做一个poc。我们正在使用scala spark。正如你所说的,只要上下文匹配,平台就不应该是问题。@Krish,不客气。请检查另一个潜在实现的更新我做了一个POC来理解这个密码,看起来我有一个问题,这里我分享了一个详细的例子。让我知道这对你是否有意义,然后我们将看到如何克服这个问题。示例:Key:mykey,groupid(nonce):10,recordId:12345,对于给定的Key和nonce,它已经生成了一些密钥流值,这很好。现在我将我的组id更改为100,这也产生了密钥流值,与组id 10产生的值相同。假设这两个组都有记录id 12345,那么这两个组都生成相同的加密文本,那么这将发出。@Krish有趣。。。我会在周末看的谢谢你的更新,我会检查并回来的。
uint64_t scramble(const uint64_t groupId,
                  const uint64_t recordId,
                  const char*    text_key = nullptr)
{
    uint8_t key[32] = {0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
                       0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
                       0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
                       0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0}; // same key as in example 3 below
    if (text_key != nullptr) {
        hex2byte(text_key, key);
    }

    const uint8_t* nonce = reinterpret_cast<const uint8_t*>(&groupId); // nonce would be our group id
    crypto_chacha_ctx ctx;
    crypto_chacha20_init(&ctx, key, nonce); // initialize ChaCha20

    crypto_chacha20_set_ctr(&ctx, recordId); // block counter is our record Id

    uint64_t input = 0x0000000000000000; // Just get the block out. Chacha will make random block and XOR it with input text.
                                         // XOR with zeroes preserve Chacha block.
                                         // Or 0xFFFFFFFFFFFFFFFF to get it iverted
    uint64_t output;
    crypto_chacha20_encrypt(&ctx,
                            reinterpret_cast<uint8_t*>(&output),
                            reinterpret_cast<const uint8_t*>(&input),
                            sizeof(input));

    return output;
}


int main()
{
    // Test values from http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04#appendix-A.2
    srand(123); //Test results will be consistent
    test_ietf_chacha20("0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586", 0, 1);
    test_ietf_chacha20("0000000000000000000000000000000000000000000000000000000000000001", "0000000000000002", "416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f", "a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d4b7955ec2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f56e031ca5eb6250d4042e02785ececfa4b4bb5e8ead0440e20b6e8db09d881a7c6132f420e52795042bdfa7773d8a9051447b3291ce1411c680465552aa6c405b7764d5e87bea85ad00f8449ed8f72d0d662ab052691ca66424bc86d2df80ea41f43abf937d3259dc4b2d0dfb48a6c9139ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b0871cdac638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6ccc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e818b04b0bc39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80ef2554d7189c411f5869ca52c5b83fa36ff216b9c1d30062bebcfd2dc5bce0911934fda79a86f6e698ced759c3ff9b6477338f3da4f9cd8514ea9982ccafb341b2384dd902f3d1ab7ac61dd29c6f21ba5b862f3730e37cfdc4fd806c22f221", 1, 2);
    test_ietf_chacha20("1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0", "0000000000000002", "2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e", "62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553ebf39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1", 42, 3);
    std::cout << '\n';

    uint64_t scrambled{0ULL};

    scrambled = scramble(10, 12345);
    std::cout << "0x" << std::hex << scrambled << '\n';
    scrambled = scramble(100, 12345);
    std::cout << "0x" << std::hex << scrambled << '\n';
    scrambled = scramble(11, 12345); // group id differ by 1
    std::cout << "0x" << std::hex << scrambled << '\n';
    scrambled = scramble(10, 12346); // record id differ by 1
    std::cout << "0x" << std::hex << scrambled << '\n';
    scrambled = scramble(0, 0);
    std::cout << "0x" << std::hex << scrambled << '\n';
    scrambled = scramble(0, 1);
    std::cout << "0x" << std::hex << scrambled << '\n';
    scrambled = scramble(1, 0);
    std::cout << "0x" << std::hex << scrambled << '\n';

    return 0;
}
0x6321d1e43d4ab340
0x7dd7e1cfab075076
0x1e8483e0081fa6ee
0xb6084d3151900667
0x7794b6c405fbf46
0x115ddf32dffd75df
0x87a199dff4e4326a