Node.js의 crypto.randomFillSync() 메서드는 버퍼(buffer)를 인자로 받아 해당 버퍼 전체 또는 일부를 암호학적으로 안전한(cryptographically secure) 난수 값으로 채운 뒤, 그 버퍼를 반환합니다. 이름에서 알 수 있듯이 이 메서드는 동기(synchronous) 방식으로 동작하며, 작업이 완료될 때까지 프로그램의 실행 흐름을 차단(blocking)합니다.
구문(Syntax)
crypto.randomFillSync(buffer, [offset], [size])
매개변수(Parameters)
위 구문에서 사용되는 매개변수는 아래와 같습니다.
buffer – 난수로 채워질 데이터의 대상입니다. 사용 가능한 타입으로는 string, TypedArray, Buffer, ArrayBuffer, DataView가 있으며, 버퍼의 크기는 2**31-1(약 2GB)을 초과할 수 없습니다.
offset – 난수 채우기가 시작될 시작 지점의 오프셋 값입니다. 기본값은 0입니다.
size – 오프셋 이후부터 채워질 버퍼의 크기, 즉 (buffer.length - offset)입니다. 이 값 역시 2**31-1을 초과할 수 없습니다.
참고: 동기 방식인 randomFillSync()는 호출 시점에 실행을 차단하므로, 큰 버퍼를 자주 다루는 서버 환경에서는 비동기 버전인 crypto.randomFill()을 사용하는 것이 성능 면에서 더 유리합니다.
예제 1: 기본 사용법
randomFillSync.js라는 이름의 파일을 생성하고 아래 코드를 복사해 넣으세요. 파일 생성 후 다음 명령어로 코드를 실행할 수 있습니다.
node randomFillSync.js
randomFillSync.js
// crypto.randomFillSync() 예제 데모
// crypto 모듈 가져오기
const crypto = require('crypto');
// 버퍼 길이 정의
const buffer = Buffer.alloc(15);
// 버퍼만 전달
console.log(crypto.randomFillSync(buffer).toString('base64'));
// 버퍼와 오프셋 전달
crypto.randomFillSync(buffer, 4);
console.log(buffer.toString('base64'));
// 버퍼, 오프셋, 크기 전달
crypto.randomFillSync(buffer, 4, 4);
console.log(buffer.toString('base64'));
출력 결과
C:\home\node>> node randomFillSync.js wVBZ+i/nvmL3Ce4kBOl0 wVBZ+hkP5DB/4Ci8yTGs wVBZ+stVWJZ/4Ci8yTGs
실행 결과를 보면 첫 번째 출력에서는 버퍼 전체(15바이트)가 난수로 채워졌고, 두 번째 출력에서는 인덱스 4부터 끝까지, 세 번째 출력에서는 인덱스 4부터 4바이트만 새로운 난수로 덮어쓰여진 것을 확인할 수 있습니다. 즉, offset과 size 매개변수를 조합하면 버퍼의 원하는 영역만 선택적으로 갱신할 수 있습니다.
예제 2: TypedArray 및 DataView 활용
이번에는 Buffer뿐 아니라 TypedArray(Int8Array, BigInt64Array)와 DataView 객체에도 randomFillSync()를 적용해 보겠습니다.
// crypto.randomFillSync() 예제 데모
// crypto 모듈 가져오기
const crypto = require('crypto');
// TypedArray 인스턴스 생성 (Int8Array)
const data = new Int8Array(16);
// 버퍼, 오프셋, 크기
console.log(Buffer.from(crypto.randomFillSync(data).buffer, data.byteOffset, data.byteLength).toString('base64'));
console.log();
// TypedArray 인스턴스 생성 (BigInt64Array)
const data2 = new BigInt64Array(4);
console.log(Buffer.from(crypto.randomFillSync(data2).buffer, data2.byteOffset, data2.byteLength).toString('ascii'));
console.log();
// DataView 인스턴스 생성
const data3 = new DataView(new ArrayBuffer(7));
console.log(Buffer.from(crypto.randomFillSync(data3).buffer, data3.byteOffset, data3.byteLength).toString('hex'));
출력 결과
C:\home\node>> node randomFillSync.js iNm8tiwDATcV6I8xjTSTbQ== ra+I=(6&Xse"hjw?!EO?D#S7M d957fb1dbdfa00
이처럼 randomFillSync()는 Buffer 객체뿐 아니라 Int8Array, BigInt64Array 같은 TypedArray나 DataView 등 다양한 바이너리 데이터 타입에 직접 적용할 수 있습니다. 각 출력은 순서대로 base64, ascii, hex 방식으로 인코딩된 결과이며, ascii 출력에 깨진 문자가 보이는 것은 난수 바이트가 printable ASCII 범위를 벗어난 값이기 때문입니다.
주요 활용 사례
암호화 키, IV(초기화 벡터), 솔트(salt) 생성
세션 토큰, 임시 비밀번호 등 보안이 중요한 난수가 필요한 경우
이미 할당된 버퍼의 특정 영역만 재사용하면서 난수를 채워야 하는 경우