Выбрать главу

s1 = "Внимание" << 7 << 7 << 7 # Добавлено три символа ASCII BEL.

puts s1.dump                   # Печатается: Внимание\007\007\007

s2 = "abc\t\tdef\tghi\n\n"

puts s2.dump                   # Печатается: abc\t\tdef\tghi\n\n

s3 = "Двойная кавычка: \""

puts s3.dump                   # Печатается: Двойная кавычка: \"

При стандартном значении переменной $KCODE метод dump дает такой же эффект, как вызов метода inspect для строки. Переменная $KCODE рассматривается в главе 4.

2.33. Генерирование последовательности строк

Изредка бывает необходимо получить «следующую» строку. Так, следующей для строки "aaa" будет строка "aab" (затем "aac", "aad" и так далее). В Ruby для этой цели есть метод succ:

droid = "R2D2"

improved = droid.succ # "R2D3"

pill = "Vitamin B"

pill2 = pill.succ     # "Vitamin C"

He рекомендуется применять этот метод, если точно не известно, что начальное значение предсказуемо и разумно. Если начать с какой-нибудь экзотической строки, то рано или поздно вы получите странный результат.

Существует также метод upto, который в цикле вызывает succ, пока не будет достигнуто конечное значение:

"Files, A".upto "Files, X" do | letter |

 puts "Opening: #{letter}"

end

# Выводится 24 строки.

Еще раз подчеркнем, что эта возможность используется редко, да и то на ваш страх и риск. Кстати, метода, возвращающего «предшествующую» строку, не существует.

2.34. Вычисление 32-разрядного CRC

Контрольный код циклической избыточности (Cyclic Redundancy Checksum, CRC) — хорошо известный способ получить «сигнатуру» файла или произвольного массива байтов. CRC обладает тем свойством, что вероятность получения одинакового кода для разных входных данных равна 1/2**N, где N — число битов результата (чаще всего 32).

Вычислить его позволяет библиотека zlib, написанная Уэно Кацухиро (Ueno Katsuhiro). Метод crc32 вычисляет CRC для строки, переданной в качестве параметра.

require 'zlib'

include Zlib

crc = crc32("Hello")        # 4157704578

crc = crc32(" world!",crc)  # 461707669

crc = crc32("Hello world!") # 461707669 (то же, что и выше)

В качестве необязательного второго параметра можно передать ранее вычисленный CRC. Результат получится такой, как если бы конкатенировать обе строки и вычислить CRC для объединения. Это полезно, например, когда нужно вычислить CRC файла настолько большого, что прочитать его можно только по частям.

2.35. Вычисление МD5-свертки строки

Алгоритм MD5 вырабатывает 128-разрядный цифровой отпечаток или дайджест сообщения произвольной длины. Это разновидность свертки, то есть функция шифрования односторонняя, так что восстановить исходное сообщение по дайджесту невозможно. Для Ruby имеется расширение, реализующее MD5; интересующиеся могут найти его в каталоге ext/md5 стандартного дистрибутива.

Для создания нового объекта MD5 есть два эквивалентных метода класса: new и md5:

require 'md5'

hash = MD5.md5

hash = MD5.new

Есть также четыре метода экземпляра: clone, digest, hexdigest и update. Метод clone просто копирует существующий объект, а метод update добавляет новые данные к объекту:

hash.update("Дополнительная информация...")

Можно создать объект и передать ему данные за одну операцию:

secret = MD5.new("Секретные данные")

Если задан строковый аргумент, он добавляется к объекту путем обращения к методу update. Повторные обращения эквивалентны одному вызову с конкатенированными аргументами:

# Эти два предложения:

сryptic.update("Данные...")

cryptic.update(" еще данные.")

# ... эквивалентны одному такому:

cryptic.update("Данные... еще данные.")

Метод digest возвращает 16-байтовую двоичную строку, содержащую 128-разрядный дайджест.

Но наиболее полезен метод hexdigest, который возвращает дайджест в виде строки в коде ASCII, состоящей из 32 шестнадцатеричных символов, соответствующих 16 байтам. Он эквивалентен следующему коду:

def hexdigest

 ret = ''

 digest.each_byte {|i| ret << sprintf{'%02x' , i) }

 ret

end

secret.hexdigest # "b30e77a94604b78bd7a7e64ad500f3c2"

Короче говоря, для получения MD5-свертки нужно написать:

require 'md5'

m = MD5.new("Секретные данные").hexdigest