cleanup: strip remaining comment noise

This commit is contained in:
“Naeel”
2026-04-30 07:53:58 +04:00
parent 0c7fd14a3a
commit a4c825db60
12 changed files with 62 additions and 275 deletions
+2 -65
View File
@@ -1,120 +1,57 @@
component /*https://www.bennadel.com/blog/2976-trying-to-generate-cryptographically-strong-random-tokens-in-coldfusion.htm*/
component
output = false
hint = "Генерирует случайные токены с помощью Java SecureRandom."
{
/**
* Инициализирует генератор токенов.
*
* @output false
*/
public any function init() {
// Реализация генератора, используемая для построения случайных токенов.
// SHA1PRNG не является алгоритмом по умолчанию во всех реализациях JVM,
// поэтому он задается явно для предсказуемого поведения.
generator = createObject( "java", "java.security.SecureRandom" )
.getInstance(
javaCast( "string", "SHA1PRNG" ),
javaCast( "string", "SUN" )
)
;
// После инициализации нужно сгенерировать случайный байт,
// чтобы генератор сам засеялся через общий источник seed.
// Это может блокироваться до накопления достаточной энтропии,
// поэтому операция выполняется при инициализации, а не при первом использовании.
generator.nextBytes( charsetDecode( " ", "utf-8" ) );
// Момент следующего пересева генератора.
// Это снижает риск слишком долгой работы с одним и тем же seed.
reseedAt = getNextReseedAt();
return( this );
}
// Публичные методы.
/**
* Генерирует криптографически стойкий токен из заданного числа случайных байтов.
* Байт-массив кодируется в форму, пригодную для использования в URL.
*
* @byteCount Количество случайных байтов для генерации токена.
* @output false
*/
public string function nextToken( numeric byteCount = 32 ) {
// Проверяем, нужен ли пересев генератора.
if ( now() >= reseedAt ) {
// Пересев выполняется под lock, чтобы уменьшить гонки между потоками.
// Если lock не получен вовремя, поток продолжает работу с текущим состоянием генератора.
lock
name = "TokenGenerator.reseedCheck"
type = "exclusive"
timeout = 1
throwOnTimeout = false
{
// Повторная проверка внутри lock: другой поток мог уже обновить seed.
if ( now() >= reseedAt ) {
reseedAt = getNextReseedAt();
// Новый seed добавляется к уже существующему внутреннему состоянию генератора.
generator.setSeed( generator.generateSeed( javaCast( "int", 32 ) ) );
}
}
}
// Создаем буфер байтов, в который будут записаны случайные значения.
var byteBuffer = charsetDecode( repeatString( " ", byteCount ), "utf-8" );
generator.nextBytes( byteBuffer );
return( encodeBytes( byteBuffer ) );
}
// Приватные методы.
/**
* Кодирует массив байтов в строку токена.
*
* @bytes Кодируемый массив байтов.
* @output false
*/
private string function encodeBytes( required binary bytes ) {
var token = binaryEncode( bytes, "base64" ); // *** вот поэтому длина отличается от заявленной
// мы хотим убрать все спецсимволы, потому что мы используем токен в качестве псевдослучайного суффикса
var token = binaryEncode( bytes, "base64" );
token = replace( token, "+", "a", "all" );
token = replace( token, "/", "b", "all" );
token = replace( token, "=", "c", "all" );
return( token );
}
/**
* Вычисляет время следующего пересева генератора.
*
* @output false
*/
private date function getNextReseedAt() {
return( dateAdd( "h", 1, now() ) );
}
}