使用Ruby使用简单hashmap替换数字数据

使用Ruby使用简单hashmap替换数字数据,ruby,hashmap,scramble,Ruby,Hashmap,Scramble,我试图想出一种简单的方法,使用Ruby对一些数字数据进行加扰(或屏蔽),以便从实时数据创建一个虚拟数据集。我希望数据尽可能接近原始格式(即保留所有非数字字符)。数据中的数字对应于单个标识号,这些标识号(有时)是关系数据库中使用的键。因此,如果数字字符串出现多次,我希望将其一致地映射到相同(理想情况下是唯一的)值。一旦数据被置乱,我就不需要能够反转置乱 我创建了一个置乱函数,它接受一个字符串并生成一个简单的散列来将数字映射到新值(该函数只映射数字,其他一切保持原样)。为了增加安全性,每次调用函数时

我试图想出一种简单的方法,使用Ruby对一些数字数据进行加扰(或屏蔽),以便从实时数据创建一个虚拟数据集。我希望数据尽可能接近原始格式(即保留所有非数字字符)。数据中的数字对应于单个标识号,这些标识号(有时)是关系数据库中使用的键。因此,如果数字字符串出现多次,我希望将其一致地映射到相同(理想情况下是唯一的)值。一旦数据被置乱,我就不需要能够反转置乱

我创建了一个置乱函数,它接受一个字符串并生成一个简单的散列来将数字映射到新值(该函数只映射数字,其他一切保持原样)。为了增加安全性,每次调用函数时,都会重新生成密钥。因此,每次调用函数时,同一短语将产生两个不同的结果

module HashModule
  def self.scramble(str)
    numHash ={}
    0.upto(9) do |i|
      numHash[i.to_s]=rand(10).to_s
    end

    output= String.new(str)
    output.gsub!(/\d/) do|d|
      d.replace numHash[d]
    end

    puts "Input: " + str
    puts "Hash Key: " + numHash.to_s
    puts "Output: " + output
  end
end

HashModule.scramble("56609-8 NO PCT 001")
HashModule.scramble("56609-8 NO PCT 001")
这将产生以下输出:

Input: 56609-8 NO PCT 001
Hash Key: {"0"=>"9", "1"=>"4", "2"=>"8", 
           "3"=>"9", "4"=>"4", "5"=>"8", 
           "6"=>"4", "7"=>"0", "8"=>"2", 
           "9"=>"1"}
Output: 84491-2 NO PCT 994

Input: 56609-8 NO PCT 001
Hash Key: {"0"=>"2", "1"=>"0", "2"=>"9", 
           "3"=>"8", "4"=>"4", "5"=>"5", 
           "6"=>"7", "7"=>"4", "8"=>"2", 
           "9"=>"0"}
Output: 57720-2 NO PCT 220
PTO NO PC
R7834913043 IP
R799922223-772
NO PCT AMB PTO
NO AMB/CALL IP
A799922223
6955509AACHM IP
13330271111111
66166777-6
鉴于数据集:

PTO NO PC
R5632893423 IP
R566788882-001
NO PCT AMB PTO
NO AMB/CALL IP
A566788882
1655543AACHM IP
56664320000000
00566333-1
我首先将所有数字提取到一个数组中。然后我使用我创建的置乱函数创建替换哈希映射,例如

 {"5632893423"=>"5467106076", "566788882"=>"888299995", 
  "001"=>"225", "1655543"=>"2466605", 
  "56664320000000"=>"70007629999999", 
  "00566333"=>"00699999", "1"=>"3"}
[顺便说一句,在我的示例中,我没有找到一种方法来坚持哈希值都是唯一的,这与正在映射的字符串对应关系数据库中的唯一ID有关,如上所述。]

我在原始字符串上使用gsub,并用加扰值替换哈希键。我的代码很有效,但我很想知道如何使它更简洁。我意识到,通过每次调用函数时重新生成键,我可以创建额外的工作。(否则,我可以只创建一个键来替换所有数字)

有没有人对我如何以另一种方式实现这一目标提出建议?(我是Ruby新手,因此改进代码的建议也被广泛接受)


也许是这样的:

module HashModule
  ScrambleKey = Hash[(0..9).map(&:to_s).zip((0..9).to_a.shuffle)]
  def self.scramble(str); str.gsub(/\d/){ScrambleKey[$&]} end
end

puts HashModule.scramble(input)
其中:

PTO NO PC
R6907580170 IP
R699455557-223
NO PCT AMB PTO
NO AMB/CALL IP
A699455557
3966610AACHM IP
69991072222222
22699000-3

除了brilliant@sawa的回答之外,我建议您直接在
String
类中“注入”这种置乱方法(使
str.scramble
项目范围内可用,不需要任何额外的屈膝礼):

这个实现引入了一个类变量,而不是一个实例变量。如果您需要字符串之间的
ScrambleKey
不同,请使用实例变量

屈服:

input = <<EOS
PTO NO PC
R5632893423 IP
R566788882-001
NO PCT AMB PTO
NO AMB/CALL IP
A566788882
1655543AACHM IP
56664320000000
00566333-1
EOS

puts input.scramble
class String
  @@ScrambleKey = Hash[(0..9).map(&:to_s).zip((0..9).to_a.shuffle)]
  def scramble ; self.gsub(/\d/) { @@ScrambleKey [$&] } end
end
input = <<EOS
PTO NO PC
R5632893423 IP
R566788882-001
NO PCT AMB PTO
NO AMB/CALL IP
A566788882
1655543AACHM IP
56664320000000
00566333-1
EOS

puts input.scramble
PTO NO PC
R1548024784 IP
R155600008-339
NO PCT AMB PTO
NO AMB/CALL IP
A155600008
9511174AACHM IP
15557483333333
33155444-9