匿名比较两个电子邮件地址列表

时间:2014-02-15 19:09:26

标签: email hash comparison

给出两个清单:

公司A:

user1@example.com

user2@example.com

user3@example.com

user4@example.com

公司B:

user2@example.com

user4@example.com

user5@example.com

有没有办法匿名比较它们以获得共同的电子邮件地址数量(即2),而两家公司都不知道哪些地址是共同的?

背景

假设公司A和公司B想知道他们的用户群的哪个部分是常见的。为简单起见,他们只是将其基于电子邮件地址,而不是关注使用多个地址或不同地址变体的用户(user+misc@example.com)。

为了保护隐私,两家公司都不能给对方提供明确的电子邮件地址列表。如果他们使用相同的简单哈希,例如MD5,每个公司都可以很容易地知道哪些成员是共同的(不是所希望的)。如果他们使用了公司特定秘密的哈希值,则地址将不再具有可比性,因此无法回答问题。

是否有一些技巧使用密钥加密或其他数学方法来完成我想要做的事情?

3 个答案:

答案 0 :(得分:0)

隐私权协议是否禁止共享电子邮件地址?或者它是一个有竞争力的问题?

如果您只是想了解重叠百分比,那么我认为电子邮件地址的简单编码可能有用。例如,对每个列表进行重复数据删除,Base64对每个电子邮件地址进行编码,然后运行比较以获得重叠,然后报告数字。

简单的NDA可能会使这个问题变得不那么简单。

答案 1 :(得分:0)

我相信在加密领域可以更好地理解这个问题。

这是secure multi-party computation的问题。

我不知道有任何针对此问题的防弹解决方案,但我可以想到以下内容:

  1. 选择一个可交换的哈希函数(H):

    H(H(string, seed1), seed2) = H(H(string, seed2), seed1)

  2. 各方(A公司和B公司)必须选择秘密种子:

    SEED_ASEED_B

  3. 公司A使用SEED_A对所有电子邮件地址进行哈希处理,公司B使用SEED_B哈希所有电子邮件地址。

  4. 他们交换了哈希。

  5. 每家公司都会在对方收到的套装上再次使用哈希函数。

  6. 此时数据应该已经是乱码,公司应该无法识别自己的电子邮件地址(因为它们已经被两次哈希 - 第二次使用未知密钥)。

  7. 所有电子邮件地址都应该公开布局,而那些具有相同哈希值的电子邮件地址应该算作属于两家公司的电子邮件地址(除非两家公司都不能告诉哈希的来源)。

  8. 这是理论。希望我没有错过任何内容,算法中没有任何缺陷。

    至于实现,这里是我可以带来的最简单的PHP脚本:

    $a = array("user1@example.com", "user2@example.com", "user3@example.com", "user4@example.com");
    $b = array("user2@example.com", "user4@example.com", "user5@example.com");
    
    function enc($str, $seed) {
        for ($i = strlen($str) - 1; $i >= 0; $i--) {
            $str[$i] = $str[$i] ^ $seed[$i % strlen($seed)];
        }
    
        return $str;
    }
    
    /* Company A */
    $hashesForB = array();
    $SEED_A = 'SALT FOR COMPANY A';
    
    foreach ($a as $address) {
        $hashesForB[] = enc($address, $SEED_A);
    }
    
    /* Company B */
    $hashesForA = array();
    $SALT_B = 'THIS IS THE SALT FOR COMPANY B';
    
    foreach ($b as $address) {
        $hashesForA[] = enc($address, $SALT_B);
    }
    
    /* Company A */
    $hashesForB_2 = array();
    
    foreach ($hashesForA as $hash) {
        $hashesForB_2[] = enc($hash, $SEED_A);
    }
    
    /* Company B */
    $hashesForA_2 = array();
    
    foreach ($hashesForB as $hash) {
        $hashesForA_2[] = enc($hash, $SALT_B);
    }
    
    $common = count(array_intersect($hashesForA_2, $hashesForB_2));
    
    print $common; // it will output 2
    

    Click here for the DEMO

    正如您在上面的代码中看到的,我使用XOR算法进行(伪)哈希(实际上,任何基于加法的哈希函数都应该完成这项工作)。

    显然,出于多种原因,这不是最佳选择:

    • XOR将在使用相同的盐
    • 的新呼叫时返回原始输入
    • 熵不是你希望的最好的
    • 数据未截断

    但是,您可以使用herehereherehere建议来实现自己的哈希函数。

答案 2 :(得分:-1)

这取决于您要使用的语言。

在python中,你可以使用这个脚本:

listA = ('user1@example.com', 'user2@example.com', 'user3@example.com')
listB = ('user1@example.com', 'user2@example.com')

result = [x for x in listA if x in listB]
print(len(result))

为了安全起见,您可以在外部服务器中托管此脚本,两家公司都可以将其放入列表中,然后检查结果。