Пакет crypto/rand
Пакет crypto/rand предоставляет функции для генерации криптографически безопасных случайных чисел. В отличие от пакета math/rand, который генерирует предсказуемые последовательности, crypto/rand использует энтропию операционной системы (например, /dev/urandom на Unix-системах или CryptGenRandom на Windows), что делает его пригодным для задач, связанных с безопасностью: создание ключей шифрования, сессионных токенов, идентификаторов, паролей и других криптографических примитивов. Основные функции пакета: Read для заполнения среза байтов случайными данными, Int для получения случайного числа в заданном диапазоне и Prime для генерации простых чисел, используемых в криптографических алгоритмах.
Основные функции
Пакет crypto/rand предоставляет три основные функции:
-
func Read(b []byte) (n int, err error)- заполняет переданный срез случайными байтами -
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)- возвращает случайное число в диапазоне [0, max) -
func Prime(rand io.Reader, bits int) (p *big.Int, err error)- генерирует простое число заданной длины в битах
Синтаксис функции Read
func Read(b []byte) (n int, err error)
Пример с функцией Read
Давайте сгенерируем 10 случайных байтов с помощью функции Read:
package main
import (
"crypto/rand"
"fmt"
)
func main() {
b := make([]byte, 10)
n, err := rand.Read(b)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Сгенерировано %d байтов: %x\n", n, b)
}
Результат выполнения кода:
"Сгенерировано 10 байтов: 4a7b9c3d2e1f8a6b5c4d"
Синтаксис функции Int
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)
Пример с функцией Int
Давайте сгенерируем случайное число от 0 до 1000:
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
func main() {
max := big.NewInt(1000)
num, err := rand.Int(rand.Reader, max)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Случайное число: %d\n", num)
}
Результат выполнения кода:
"Случайное число: 742"
Синтаксис функции Prime
func Prime(rand io.Reader, bits int) (p *big.Int, err error)
Пример с функцией Prime
Давайте сгенерируем простое число длиной 128 бит:
package main
import (
"crypto/rand"
"fmt"
)
func main() {
prime, err := rand.Prime(rand.Reader, 128)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Простое число: %d\n", prime)
}
Результат выполнения кода:
"Простое число: 241031242692103258855207602219756607381"
Генерация безопасного токена
Пакет crypto/rand часто используется для создания безопасных токенов и ключей. Давайте сгенерируем случайную строку для использования в качестве сессионного токена:
package main
import (
"crypto/rand"
"encoding/base64"
"fmt"
)
func main() {
b := make([]byte, 32)
_, err := rand.Read(b)
if err != nil {
fmt.Println(err)
return
}
token := base64.URLEncoding.EncodeToString(b)
fmt.Printf("Сессионный токен: %s\n", token)
}
Результат выполнения кода:
"Сессионный токен: x7f9Kp2Qv5Rc3Wm8Nt1Lb4Jh6Gd2Ea9S"
Использование пользовательского ридера
Функции Int и Prime принимают параметр io.Reader. Это позволяет использовать собственный источник энтропии или обернуть стандартный ридер для дополнительной обработки:
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
func main() {
max := big.NewInt(100)
num, err := rand.Int(rand.Reader, max)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Случайное число от 0 до 99: %d\n", num)
}
Результат выполнения кода:
"Случайное число от 0 до 99: 73"
Особенности и предостережения
При работе с пакетом crypto/rand следует учитывать несколько важных моментов. Во-первых, функции этого пакета могут блокироваться, если в системе недостаточно энтропии. Во-вторых, для большинства задач рекомендуется использовать rand.Reader как стандартный источник случайности. В-третьих, не используйте crypto/rand для задач, не связанных с безопасностью, так как его работа медленнее по сравнению с math/rand и может излишне расходовать системную энтропию.
Также важно помнить, что сгенерированные данные не подходят для воспроизводимых сценариев, поскольку их нельзя предсказать или получить повторно. Если вам нужна воспроизводимость, используйте math/rand с явным начальным числом.
Смотрите также
-
функцию
crypto/rand.Read,
которая заполняет срез случайными байтами -
функцию
crypto/rand.Int,
которая генерирует случайное число в заданном диапазоне -
функцию
crypto/rand.Prime,
которая генерирует криптографически безопасное простое число -
пакет
crypto,
который объединяет все криптографические пакеты Go