有两件事对你来说似乎很重要
- 匿名
- 参照完整性
对于您的两个要求,您链接的博客文章中的解决方案是一个糟糕的选择。
匿名
只是散列不提供匿名性。该文章还提到(但它不在代码中)您可能至少想要添加盐。
只是一个例子:
像这样的数字211
将af9fad5f
作为 CRC32 散列。如果您与之共享数据的人看到这个 8char(32bit) 字母数字字符串,它可能会认为这可能是一个 CRC32 哈希。哈希的好处是你不能轻易地从af9fad5f
to开始计算211
。坏事是,大多数短词/哈希已经预先计算好,并且很容易在所谓的彩虹表中查找(例如https://md5hashing.net/hash/crc32/af9fad5f)。
这基本上意味着每个人都可以查找 crc32 哈希后面的“明文”。(所有其他哈希相同)。添加盐可以防止这种情况。(这种盐当然要保密!)
参照完整性
保持参照完整性。211
将始终af9fad5f
作为 CRC32 散列 - 这是静态的,没有随机效应。因此,所有表的 Product_ID 都将保持不变。这就是你需要的。
但只是为了确保我会使用 SHA256 而不是 CRC32。在 CRC32 中,所有内容都将映射到 8chars 字母数字(32 位)。如果你有很多数据 - 有一些哈希冲突的可能性。这意味着同一个表中的两个数字/ID 实际上具有相同的哈希值。使用 SHA256,这几乎是不可能的。
总的来说,我认为使用匿名程序包似乎没问题。(它没有被积极维护 - 但功能似乎还可以)
install.packages("devtools")
devtools::install_github("paulhendricks/anonymizer")
# Some test data
testdata <- data.frame(t1 = c(211,11,9), t2 = c(2,3,9))
anonymizer::anonymize(testdata$t1, .algo = "sha256", .seed = 1)
anonymizer::anonymize(testdata$t2, .algo = "sha256", .seed = 1)
t1
[1] "9ebb37da5a7e1db2a0ff7d0e9aa6df5b6d27a5928ce0454a9e71655cf5a16e46"
[2] "ec3e0f47c01a40969f933b9179edee184bc2d57a77e1941fc1fe773c8ac429b6"
[3] "14439a3c932d0f133ac5f5f9b147be16b4ffd854664b58fcae922084da984e2e"
t2
[1] "03a5ed142ba102af5c8e4328f54c8785310b7a8f1881b3bb9d1803261b64e91a"
[2] "0b65dd05edbd9154c3668ce294ca875e1d079967051c06238516d1a0bb233b7c"
[3] "14439a3c932d0f133ac5f5f9b147be16b4ffd854664b58fcae922084da984e2e"
testdata$t1
和你一样,最后一个哈希值testdata$t2
是相同的,因为它都是 9 的时间。
我想到的另一个包是匿名器,但它看起来只将几列视为敏感,并且在屏蔽时将数字转换为字母数字。
你是什么意思?你想让你的值被数值掩盖吗?(为此,您可以在 R 中将字符串转换为数值)。但至少对于产品 ID,我并没有真正看到好处。
评论补充:
@Steffen,我们能否以某种方式仅用数字替换数值。例如,SSN 是 9 位数字,我只想将其替换为另一个 9 位数字。
是的,但与上面概述的基于散列的解决方案相比不是很好。可能需要您编写更多代码。这需要非常小心地完成,因为在确保引用完整性、避免串通和防止重新识别的同时很容易遗漏某些东西)。我真的会尝试使用现有的解决方案。
您还可以查看 R 中的sdcMicro包。我认为它们没有参考完整性部分的内容。但是您可以通过加入表然后使用匿名化函数(这样,例如 product_id 只会在一个列中)然后再次拆分为两个数据集来规避这个问题。
我认为使用其他工具进行匿名化可能也是一个好主意 - 看看这个开源工具ARX – 数据匿名化工具
像这样的外部 GUI 工具的缺点是,如果您计划不止一次地创建匿名数据集,这可能不是一个好主意。由于您没有程序,您可以运行它。