модуль SecureRandom
Интерфейс генератора случайных чисел.
Эта библиотека — интерфейс для генератора случайных чисел, подходящего для генерации ключей сессий в HTTP-куках и т. п.
Вы можете использовать эту библиотеку в своём приложении, подключив её:
require 'securerandom'
Она поддерживает следующие генераторы случайных чисел.
-
openssl
-
/dev/urandom
-
Win32
Примеры
Шестнадцатеричная строка.
require 'securerandom' p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362" p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559" p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
База64 строка.
p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA==" p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg==" p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
Бинарная строка.
p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
Методы публичного класса
# File lib/securerandom.rb, line 192
def self.base64(n=nil)
[random_bytes(n)].pack("m*").delete("\n")
end ::base64 генерирует случайную строку в формате Base64.
Аргумент n задаёт длину, в байтах, случайного числа, подлежащего генерации. Длина результирующей строки составляет приблизительно 4/3 от n.
Если n не указан или равен nil, используется значение 16. В будущем оно может быть больше.
Результат может содержать символы A-Z, a-z, 0-9, “+”, “/” и “=”.
p SecureRandom.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A==" p SecureRandom.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
Если генератор случайных чисел недоступен, генерируется исключение NotImplementedError.
См. RFC 3548 для определения Base64.
# File lib/securerandom.rb, line 113
def self.gen_random(n)
@pid = 0 unless defined?(@pid)
pid = $$
unless @pid == pid
now = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
ary = [now, @pid, pid]
OpenSSL::Random.random_add(ary.join("").to_s, 0.0)
@pid = pid
end
return OpenSSL::Random.random_bytes(n)
end # File lib/securerandom.rb, line 171
def self.hex(n=nil)
random_bytes(n).unpack("H*")[0]
end ::hex генерирует случайную шестнадцатеричную строку.
Аргумент n задаёт длину, в байтах, случайного числа, подлежащего генерации. Длина результирующей шестнадцатеричной строки составляет удвоенное значение n.
Если n не указан или равен nil, используется значение 16. В будущем оно может быть больше.
Результат может содержать символы 0-9 и a-f.
p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485" p SecureRandom.hex #=> "91dc3bfb4de5b11d029d376634589b61"
Если генератор случайных чисел недоступен, генерируется исключение NotImplementedError.
# File lib/securerandom.rb, line 107 def self.random_bytes(n=nil) n = n ? n.to_int : 16 gen_random(n) end
::random_bytes генерирует случайную бинарную строку.
Аргумент n задаёт длину результирующей строки.
Если n не указан или равен nil, используется значение 16. В будущем оно может быть больше.
Результат может содержать любые байты: “x00” - “xff”.
p SecureRandom.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6" p SecureRandom.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
Если генератор случайных чисел недоступен, генерируется исключение NotImplementedError.
# File lib/securerandom.rb, line 246
def self.random_number(n=0)
if 0 < n
if defined? OpenSSL::BN
OpenSSL::BN.rand_range(n).to_i
else
hex = n.to_s(16)
hex = '0' + hex if (hex.length & 1) == 1
bin = [hex].pack("H*")
mask = bin[0].ord
mask |= mask >> 1
mask |= mask >> 2
mask |= mask >> 4
begin
rnd = SecureRandom.random_bytes(bin.length)
rnd[0] = (rnd[0].ord & mask).chr
end until rnd < bin
rnd.unpack("H*")[0].hex
end
else
# assumption: Float::MANT_DIG <= 64
if defined? OpenSSL::BN
i64 = OpenSSL::BN.rand(64, -1).to_i
else
i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
end
Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)
end
end ::random_number генерирует случайное число.
Если в качестве n задано положительное целое число, ::random_number возвращает целое число: 0 <= ::random_number < n.
p SecureRandom.random_number(100) #=> 15 p SecureRandom.random_number(100) #=> 88
Если задано 0 или аргумент отсутствует, ::random_number возвращает число с плавающей точкой: 0.0 <= ::random_number < 1.0.
p SecureRandom.random_number #=> 0.596506046187744 p SecureRandom.random_number #=> 0.350621695741409
# File lib/securerandom.rb, line 222
def self.urlsafe_base64(n=nil, padding=false)
s = [random_bytes(n)].pack("m*")
s.delete!("\n")
s.tr!("+/", "-_")
s.delete!("=") unless padding
s
end ::urlsafe_base64 генерирует случайную URL-безопасную строку в формате Base64.
Аргумент n задаёт длину, в байтах, случайного числа, подлежащего генерации. Длина результирующей строки составляет приблизительно 4/3 от n.
Если n не указан или равен nil, используется значение 16. В будущем оно может быть больше.
Булевый аргумент padding задаёт включение/исключение заполнения. Если он равен false или nil, заполнение не генерируется. В противном случае заполнение генерируется. По умолчанию заполнение не генерируется, так как “=” может использоваться в качестве разделителя URL.
Результат может содержать символы A-Z, a-z, 0-9, “-” и “_”. “=” также используется, если padding равен true.
p SecureRandom.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg" p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg" p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ==" p SecureRandom.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
Если генератор случайных чисел недоступен, генерируется исключение NotImplementedError.
См. RFC 3548 для определения URL-безопасной Base64.
# File lib/securerandom.rb, line 286
def self.uuid
ary = self.random_bytes(16).unpack("NnnnnN")
ary[2] = (ary[2] & 0x0fff) | 0x4000
ary[3] = (ary[3] & 0x3fff) | 0x8000
"%08x-%04x-%04x-%04x-%04x%08x" % ary
end ::uuid генерирует случайный UUID v4 (универсальный уникальный идентификатор).
p SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594" p SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab" p SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
UUID версии 4 является чисто случайным (кроме версии). Он не содержит значимой информации, такой как адрес MAC, время и т. п.
См. RFC 4122 для подробностей о UUID.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.