【问题标题】:Obfuscating numbers in a string?混淆字符串中的数字?
【发布时间】:2013-12-03 21:40:32
【问题描述】:

我有一个挑战,要求对字符串中的数字进行混淆,例如 SSN,例如:XXX-XX-4430。我已经很接近了:

def hide_all_ssns(string)
  string.scan(/\w{3}-\w{2}-\w{4}/)
  string.gsub('/\w{3}-\w{2}', 'XXX-XX')
end

但我得到一个错误:

Error! hide_all_ssns obfuscates any SSNs in the string expected:
"XXX-XX-1422, XXX-XX-0744, XXX-XX-8762" got: "234-60-1422,
350-80-0744, 013-60-8762" (using ==)

我最初有正则表达式(/\d{3}-\d{2}-\d{4}/),但认为问题在于尝试将字符串中的整数转换为X。现在我使用\w,但我得到了同样的错误。

有人有什么见解吗?我是编码新手,已经用尽了 Ruby-doc,以及我可以在 regex/gsub 上找到的任何博客,但我无处可去。

【问题讨论】:

  • 你想改变string吗?如果是这样,设置string = string.gsub... 或使用string.gsub!
  • 我有点怀疑你已经用尽了 Ruby-doc 以及你可以在 regex/gsub 上找到的所有博客。
  • 谢谢大家,我找到了答案。不幸的是,作为编码的新手,很容易花几个小时挖掘却仍然找不到答案 - 感谢您抽出宝贵时间发表评论。

标签: ruby regex gsub


【解决方案1】:

您误用了gsub(您的正则表达式需要在正斜杠之间),但我仍然认为gsub! 是您想要的...

def hide_all_ssns(string)
  string.scan(/\w{3}-\w{2}-\w{4}/)
  string.gsub!(/\w{3}-\w{2}/, 'XXX-XX')
end

工作示例:

1.9.3p448 :063 > string = "123-45-6789"
 => "123-45-6789" 

1.9.3p448 :064 > def hide_all_ssns(string)
1.9.3p448 :065?>   string.scan(/\w{3}-\w{2}-\w{4}/)
1.9.3p448 :066?>   string.gsub!(/\w{3}-\w{2}/, 'XXX-XX')
1.9.3p448 :067?> end
 => nil 

1.9.3p448 :068 > hide_all_ssns(string)
 => "XXX-XX-6789" 

1.9.3p448 :069 > string
 => "XXX-XX-6789" 

【讨论】:

  • 所以我在 ping 一个朋友之后发现了它 - 我错过了最后的正斜杠并且不必要地在正则表达式代码周围有 ' '。非常感谢您的回答和见解,对刚开始的人很有帮助!
【解决方案2】:

为什么要这么难?所有美国社会安全号码都是same format,对吗?所以,从那一点开始工作。以下是一个主题的一些变体,按逐渐模糊的顺序排列:

ssn = '123-45-6789'   # => "123-45-6789"
ssn[0, 6] = 'XXX-XX'  # => "XXX-XX"
ssn                   # => "XXX-XX-6789"

或者:

numbers = ssn.scan(/\d+/)  # => ["123", "45", "6789"]
'XXX-XX-' + numbers.last   # => "XXX-XX-6789"

或者:

ssn = '123-45-6789'                    # => "123-45-6789"
ssn[0, 6] = ssn[0, 6].gsub(/\d/, 'X')  # => "XXX-XX"
ssn                                    # => "XXX-XX-6789"

或者:

ssn[0,6] = ssn[0, 6].tr('0-9', 'X')  # => "XXX-XX"
ssn                                  # => "XXX-XX-6789"

或者:

numbers = ssn.split('-')                                         # => ["123", "45", "6789"]
[*numbers[0, 2].map{ |s| 'X' * s.size }, numbers[-1]].join('-')  # => "XXX-XX-6789"

或者:

ssn[/(\d+)-(\d+)-(\d+)/]                                       # => "123-45-6789"
[$1, $2, $3]                                                   # => ["123", "45", "6789"]
[$3, *[$2, $1].map{ |s| s.gsub(/./, 'X') }].reverse.join('-')  # => "XXX-XX-6789"

当然,使用其中之一会作弊,因为您应该自己解决挑战,但它们是值得思考的好食物,也是您自己解决方案的一个不错的起点。

【讨论】:

  • 感谢 Tin Man - 我想通了,很高兴我能够做到这一点而没有“作弊”。感谢您的帮助!
【解决方案3】:

简短而简单...您可以尝试以下方法:

crypted = ('X' * 6) + "4543-2329-1354-1111".to_s[14..18]
=> "XXXXXX-1111"

【讨论】:

  • 哇,非常感谢您的洞察力!我得到了工作的代码 - 我错过了一个正斜杠。我肯定会将此称为重构我的代码的一种方式 - 你太棒了!感谢您的帮助。
  • @mala_sf 别担心 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 2017-05-16
  • 1970-01-01
  • 2011-04-03
  • 1970-01-01
  • 2011-03-14
相关资源
最近更新 更多