Ruby ZeroDivisionError - PullRequest
       1

Ruby ZeroDivisionError

0 голосов
/ 25 апреля 2018

Я пытаюсь создать алгоритм шифрования в рубине. Шифрование работает нормально, но дешифрование не выполняется. Ошибка находится в строке 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 голосов
/ 26 апреля 2018

На ваш вопрос ответили, но я бы хотел предложить более похожий на 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', поэтому Ruby преобразует 't' в пустую строку. Точно так же символы ' ' (пробел) и '.' (точка) не являются ключами в 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' равны Диапазон с. См. Документы для Enumerable # zip и Array # to_h . Обычно мы записываем эти две строки как одно цепочечное выражение.

encode = ('a'..'z').zip('01'..'26').to_h

Обратите внимание, что значения начинаются с "01", так что все строки одинаковой длины (2). Если мы начали значения с "1", как мы могли бы декодировать строку "1226"? Будет ли это 'abbd' (1-2-3-4), 'abz' (1-2-26), 'lz' (12-26) или одна из других возможностей. Это не проблема, если все значения хеша encode являются строками длины 2.

Мы могли бы создать хеш для декодирования таким же образом ({'01'=>'a', '02'=>'b',...}), но проще использовать метод Hash # invert :

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

Если строка для шифрования

str = "how now, brown cow."

мы можем закодировать его с помощью

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

, который затем может быть декодирован с помощью

decoded = encrypted.gsub(/../, decode)
  #=> "how now, brown cow."

Обратите внимание, что регулярное выражение ("regex") для декодирования совпадает с любыми двумя символами одновременно.

Два очка. Во-первых, мы могли бы использовать Hash # update (он же merge!) для записи

encode = ('a'..'z').zip('01'..'26').to_h
encode.update( ' '=>"27", '.'=>"28" )

Ruby позволяет писать encode.update({ ' '=>"27", '.'=>"28" }) без фигурных скобок (пример синтаксический сахар ).

Лучше использовать Hash # default_proc = для записи

encode = ('a'..'z').zip('01'..'26').to_h
encode.default_proc = proc { |h,k| h[k] = k }

Это немного сложно для новичка из Ruby, но в результате encode[k] возвращает k, если encode не имеет ключа k. Например, encode['.'] #=> '.'.

0 голосов
/ 25 апреля 2018

Не работает, потому что формула 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.)

Ваша ошибка - именно то, что написано в сообщении: вы делите на 0.

РЕДАКТИРОВАТЬ: В качестве небольшого бонуса, ваш код все равно сломан. Например, 'k' преобразуется в 11, но при расшифровке это превращается в 'aa'

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...