Ruby ZeroDivisionError

时间:2018-04-25 10:31:43

标签: ruby

我正在尝试在ruby中创建加密alghoritm。加密工作正常,但解密部分失败。错误在第67行,并说明如下:

  

decryption.rb:67:ln'/':除以零(ZeroDivisionError)

我不知道为什么会这样,我无法在网上找到答案。

这是源代码:

print ">"

ciphertext = gets.chomp

print ">"

symetricKey = gets.chomp

symetricKey.gsub! 'a', '1'
symetricKey.gsub! 'b', '2'
symetricKey.gsub! 'c', '3'
symetricKey.gsub! 'd', '4'
symetricKey.gsub! 'e', '5'
symetricKey.gsub! 'f', '6'
symetricKey.gsub! 'g', '7'
symetricKey.gsub! 'h', '8'
symetricKey.gsub! 'i', '9'
symetricKey.gsub! 'j', '10'
symetricKey.gsub! 'k', '11'
symetricKey.gsub! 'l', '12'
symetricKey.gsub! 'm', '13'
symetricKey.gsub! 'n', '14'
symetricKey.gsub! 'o', '15'
symetricKey.gsub! 'p', '16'
symetricKey.gsub! 'q', '17'
symetricKey.gsub! 'r', '18'
symetricKey.gsub! 's', '19'
symetricKey.gsub! 't', '20'
symetricKey.gsub! 'u', '21'
symetricKey.gsub! 'v', '22'
symetricKey.gsub! 'w', '23'
symetricKey.gsub! 'x', '24'
symetricKey.gsub! 'y', '25'
symetricKey.gsub! 'z', '26'

symetricKey=symetricKey.to_i

ciphertext.gsub! 'a', '1'
ciphertext.gsub! 'b', '2'
ciphertext.gsub! 'c', '3'
ciphertext.gsub! 'd', '4'
ciphertext.gsub! 'e', '5'
ciphertext.gsub! 'f', '6'
ciphertext.gsub! 'g', '7'
ciphertext.gsub! 'h', '8'
ciphertext.gsub! 'i', '9'
ciphertext.gsub! 'j', '10'
ciphertext.gsub! 'k', '11'
ciphertext.gsub! 'l', '12'
ciphertext.gsub! 'm', '13'
ciphertext.gsub! 'n', '14'
ciphertext.gsub! 'o', '15'
ciphertext.gsub! 'p', '16'
ciphertext.gsub! 'q', '17'
ciphertext.gsub! 'r', '18'
ciphertext.gsub! 's', '19'
ciphertext.gsub! 't', '20'
ciphertext.gsub! 'u', '21'
ciphertext.gsub! 'v', '22'
ciphertext.gsub! 'w', '23'
ciphertext.gsub! 'x', '24'
ciphertext.gsub! 'y', '25'
ciphertext.gsub! 'z', '26'

ciphertext = ciphertext.to_i

cleartext = ciphertext / (symetricKey / symetricKey / 100)

print"\n"

cleartext.to_s

cleartext.gsub! '1' ,'a'
cleartext.gsub! '2' ,'b'
cleartext.gsub! '3' ,'c'
cleartext.gsub! '4' ,'d'
cleartext.gsub! '5' ,'e'
cleartext.gsub! '6' ,'f'
cleartext.gsub! '7' ,'g'
cleartext.gsub! '8' ,'h'
cleartext.gsub! '9' ,'i'
cleartext.gsub! '10' ,'j'
cleartext.gsub! '11' ,'k'
cleartext.gsub! '12' ,'l'
cleartext.gsub! '13' ,'m'
cleartext.gsub! '14' ,'n'
cleartext.gsub! '15' ,'o'
cleartext.gsub! '16' ,'p'
cleartext.gsub! '17' ,'q'
cleartext.gsub! '18' ,'r'
cleartext.gsub! '19' ,'s'
cleartext.gsub! '20' ,'t'
cleartext.gsub! '21' ,'u'
cleartext.gsub! '22' ,'v'
cleartext.gsub! '23' ,'w'
cleartext.gsub! '24' ,'x'
cleartext.gsub! '25' ,'y'
cleartext.gsub! '26' ,'z'

puts cleartext

2 个答案:

答案 0 :(得分:6)

它不起作用,因为公式ciphertext / (symetricKey / symetricKey / 100)完全没有意义。

  1. symetricKey / symetricKey始终为1,除以100,始终为0.01
  2. symetricKey / symetricKey / 100两个操作数都是整数,因此0.01向下舍入为0
  3. ciphertext / (symetricKey / symetricKey / 100)相当于ciphertext / 0(参见2.)
  4. 您的错误正如消息中所说的那样:您将除以0。

    编辑:作为一个小小的奖励,无论如何你的代码都被打破了。例如,'k'已转换为11,但在解密时会转换为'aa'

答案 1 :(得分:0)

您的问题已得到解答,但我想建议一种类似Ruby的方法来解决您的问题。

如果您查看Hash#gsub的文档,您会看到该方法的第二种形式,即str.gsub(pattern, hash),其中pattern通常是正则表达式,hash当然是哈希。这是一个例子。

h = { 'c'=>'C', 'a'=>'A', 'n'=>'N', 'd'=>'D', 'o'=>'$', 'g'=>'G' }

'cat and dog.'.gsub(/./, h)
  #=> "CAANDD$G"

/./是一个正则表达式,只匹配str中的任何一个字符。它首先匹配'c',然后匹配'a',依此类推。考虑第一个字母'c'。 Ruby检查哈希h是否有密钥'c'。确实如此,因此哈希值'c'中的'C'值将替换为'a'。接下来,'A'将替换为h't'没有键't',因此Ruby会将' '转换为空字符串。同样,字符'.'(空格)和h(句点)不是gsub中的键,因此这些字符也会转换为空字符串。

这种形式的arr = ('a'..'z').zip('01'..'26') #=> [["a", "01"], ["b", "02"],..., ["z", "26"]] encode = arr.to_h #=> {"a"=>"01", "b"=>"02",..., "z"=>"26"} encode[' '] = "27" encode['.'] = "28" 似乎非常适合加密和解密字符串。

让我们首先构造编码哈希。

encode
  #=> {"a"=>"01", "b"=>"02",..., "z"=>"26", " "=>"27", "."=>"." }

所以现在

'a'..'z'

'01'..'2'encode = ('a'..'z').zip('01'..'26').to_h Range。请参阅Enumerable#zipArray#to_h的文档。我们通常将这两行写为单个链式表达式。

"01"

请注意,值以"1"开头,因此所有字符串都是相同长度的字符串(2)。如果我们使用"1226"启动值,我们如何解码字符串'abbd'?那会是'abz'(1-2-3-4),'lz'(1-2-26),encode(12-26)还是其中一种可能性。如果散列{'01'=>'a', '02'=>'b',...}的所有值都是长度为2的字符串,那么这不是问题。

我们可以用相同的方式(decode = encode.invert #=> {"01"=>"a", "02"=>"b",..., "26"=>"z", "27"=>" ", "28"=>"."} )构造用于解码的哈希,但是使用方法Hash#invert更容易:

str = "how now, brown cow."

如果要加密的字符串是

encrypted = str.gsub(/./, encode)
  #=> "081523271415232702181523142703152328"

我们可以用

对其进行编码
decoded = encrypted.gsub(/../, decode)
  #=> "how now, brown cow."

然后可以用

解码
merge!

请注意,解码的正则表达式(" regex")一次匹配任意两个字符。

两点。首先,我们可以使用Hash#update(又名encode = ('a'..'z').zip('01'..'26').to_h encode.update( ' '=>"27", '.'=>"28" ) )来编写

encode.update({ ' '=>"27", '.'=>"28" })

Ruby允许我们在没有大括号的情况下编写encode = ('a'..'z').zip('01'..'26').to_h encode.default_proc = proc { |h,k| h[k] = k } syntactic sugar的示例)。

更好的方法是使用Hash#default_proc=来编写

encode[k]

这对于Ruby新手来说有点复杂,但如果k没有密钥encode,效果会导致k返回encode['.'] #=> '.'。例如,List<...>