KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Хэл Фултон - Программирование на языке Ruby

Хэл Фултон - Программирование на языке Ruby

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Хэл Фултон, "Программирование на языке Ruby" бесплатно, без регистрации.
Перейти на страницу:

Ниже показано тривиальное приложение, которое запрашивает пароль, знакомый любителям Толкиена:

coded = "hfCghHIE5LAM."


puts "Говори, друг, и жми Enter!"


print "Пароль: " password = gets.chop


if password.crypt("hf") == coded

 puts "Добро пожаловать!"

else

 puts "Кто ты, орк?"

end

Стоит отметить, что на такое шифрование не стоит полагаться в серверных Web-приложениях, поскольку пароль, введенный в поле формы, все равно передаётся по сети в открытом виде. В таких случаях проще всего воспользоваться протоколом SSL (Secure Sockets Layer). Разумеется, никто не запрещает пользоваться шифрованием на сервере, но по другой причине — чтобы защитить пароль в хранилище, а не во время передачи по сети.

2.27. Сжатие строк

Для сжатия строк и файлов применяется библиотека Zlib.

Зачем может понадобиться сжимать строки? Возможно, чтобы ускорить ввод/вывод из базы данных, оптимизировать использование сети или усложнить распознавание строк.

В классах Deflate и Inflate имеются методы класса deflate и inflate соответственно. У метода deflate (он выполняет сжатие) есть дополнительный параметр, задающий режим сжатия. Он определяет компромисс между качеством сжатия и скоростью. Если значение равно BEST_COMPRESSION, то строка сжимается максимально, но это занимает сравнительно много времени. Значение BEST_SPEED задает максимальную скорость, но при этом строка сжимается хуже. Подразумеваемое по умолчанию значение DEFAULT_COMPRESSION выбирает компромиссный режим.

require 'zlib'

include Zlib


long_string = ("abcde"*71 + "defghi"*79 + "ghijkl"*113)*371

# long_string состоит из 559097 символов.


s1 = Deflate.deflate(long_string,BEST_SPEED) # 4188 символов.

s3 = Deflate.deflate(long_string) # 3568 символов

s2 = Deflate.deflate(long_string,BEST_COMPRESSION) # 2120 символов

Неформальные эксперименты показывают, что скорость отличается примерно в два раза, а плотность сжатия — в обратной пропорции на ту же величину. И скорость, и плотность сильно зависят от состава строки. Разумеется, на скорость влияет и имеющееся оборудование.

Имейте в виду, что существует пороговое значение длины строки. Если строка короче, то сжимать ее практически бесполезно (если только вы не хотите сделать ее нечитаемой). В этом случае неизбежные накладные расходы могут даже привести к тому, что сжатая строка окажется длиннее исходной.

2.28. Подсчет числа символов в строке

Метод count подсчитывает число вхождений в строку символов из заданного набора:

s1 = "abracadabra"

a = s1.count("с")   # 1

b = s1.count("bdr") # 5

Строковый параметр ведет себя как простое регулярное выражение. Если он начинается с символа ^, то берется дополнение к списку:

c = s1.count("^а")    # 6

d = s1.count ("^bdr") # 6

Дефис обозначает диапазон символов:

e = s1.count("a-d")  # 9

f = s1.count("^a-d") # 2

2.29. Обращение строки

Для обращения строки служит метод reverse (или его вариант для обращения «на месте» reverse!):

s1 = "Star Trek"

s2 = s1.reverse # "kerT ratS"

si.reverse!     # si теперь равно "kerT ratS"

Пусть требуется обратить порядок слов (а не символов). Тогда можно сначала воспользоваться методом String#split, который вернет массив слов. В классе Array тоже есть метод reverse, поэтому можно обратить массив, а затем с помощью метода join объединить слова в новую строку:

phrase = "Now here's a sentence"

phrase.split(" ").reverse.join(" ")

# "sentence a here's Now"

2.30. Удаление дубликатов

Цепочки повторяющихся символов можно сжать до одного методом squeeze:

s1 = "bookkeeper"

s2 = s1.squeeze # "bokeper"

s3 = "Hello..."

s4 = s3.squeeze # "Helo."

Если указан параметр, то будут удаляться только дубликаты заданных в нем символов:

s5 = s3.squeeze(".") # "Hello."

Этот параметр подчиняется тем же правилам, что и параметр метода count (см. раздел 2.28), то есть допускаются дефис и символ ^. Имеется также метод squeeze!.

2.31. Удаление заданных символов

Метод delete удаляет из строки те символы, которые включены в список, переданный в качестве параметра:

s1 = "To be, or not to be"

s2 = s1.delete("b")  # "To e, or not to e"

s3 = "Veni, vidi, vici!"

s4 = s3.delete(",!") # "Veni vidi vici"

Этот параметр подчиняется тем же правилам, что и параметр метода count (см. раздел 2.28), то есть допускаются символы - (дефис) и ^ (каре). Имеется также метод delete!.

2.32. Печать специальных символов

Метод dump позволяет получить графическое представление символов, которые обычно не печатаются вовсе или вызывают побочные эффекты:

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

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

s2 = "abcttdeftghinn"

puts s2.dump                   # Печатается: abcttdeftghinn

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-разрядный дайджест.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*