node.js에서 ID로 사용할 랜덤 SHA1 해시를 생성하는 방법?
node.js에 대한 sha1 ID를 생성하기 위해 이 줄을 사용합니다.
crypto.createHash('sha1').digest('hex');
문제는 매번 똑같은 아이디를 돌려준다는 것입니다.
데이터베이스 문서 id로 사용할 수 있도록 매번 랜덤 id를 생성할 수 있습니까?
243,583,606,221,817,150,598,111,409배 더 많은 엔트로피
crypto.randomBytes를 사용하는 것을 추천합니다.그런거 아냐.sha1
"" 를 는합니다.
var id = crypto.randomBytes(20).toString('hex');
//=> f26d60305dae929ef8640a75e70dd78ab809cfe9
결과 문자열은 생성한 임의 바이트보다 두 배 더 길며, 각 바이트는 2자이고, 20바이트는 40자의 16진수가 됩니다.
우리는 20바이트를 사용해서.256^20
또는 1,461,501,637,330,902,918,203,684,832,716,283,019,655,932,542,976개의 고유 출력 값.이는 SHA1의 160비트(20바이트) 출력과 동일합니다.
가 에 은 큰shasum
우리의 무작위 바이트들.다이를 두 번 굴리되 두 번째 롤만 받아들이는 것과 같습니다. 무슨 일이 있어도 각 롤마다 6개의 가능한 결과가 있으므로 첫 번째 롤이면 충분합니다.
왜 이게 더 좋습니까?
이것이 더 나은 이유를 이해하려면 먼저 해시 기능이 어떻게 작동하는지 이해해야 합니다.해싱 기능(SHA1 포함)은 동일한 입력이 주어지면 항상 동일한 출력을 생성합니다.
ID를 생성하고 싶지만 동전 던지기를 통해 임의 입력이 생성된다고 가정합니다.우리는 가지고 있다."heads"
아니면"tails"
% echo -n "heads" | shasum
c25dda249cdece9d908cc33adcd16aa05e20290f -
% echo -n "tails" | shasum
71ac9eed6a76a285ae035fe84a251d56ae9485a4 -
한다면"heads"
SHA1 출력이 처음과 동일하게 다시 나타납니다.
% echo -n "heads" | shasum
c25dda249cdece9d908cc33adcd16aa05e20290f -
좋아요, 그럼 동전 던지기는 가능한 출력이 2개밖에 없기 때문에 좋은 랜덤 ID 생성기가 아닙니다.
표준 6면 다이를 사용하면 6개의 입력이 가능합니다.SHA1 출력이 얼마나 되는지 맞춰보세요. 6!
input => (sha1) => output
1 => 356a192b7913b04c54574d18c28d46e6395428ab
2 => da4b9237bacccdf19c0760cab7aec4a8359010b0
3 => 77de68daecd823babbb58edb1c8e14d7106e83bb
4 => 1b6453892473a467d07372d45eb05abc2031647a
5 => ac3478d69a3c81fa62e60f5c3696165a4e5e6ac4
6 => c1dfd96eea8cc2b62785275bca38ac261256e278
우리 기능의 출력이 매우 무작위해 보인다는 이유만으로 우리 자신을 착각하기 쉽습니다.
가능한 SHA1 결과(ID에 사용하는 값)가 매우 적기 때문에 코인 토스 또는 6면 다이가 나쁜 랜덤 ID 생성기가 될 것이라는 데 우리 둘 다 동의합니다.하지만 출력이 훨씬 더 많은 것을 사용한다면 어떨까요?밀리초 타임스탬프 같은 거?아니면 자바스크립트의Math.random
? 아니면 그 둘의 조합이라도?!
몇 개의 고유 ID를 얻을 수 있는지 계산해 보겠습니다.
밀리초가 있는 타임스탬프의 고유성
.(new Date()).valueOf().toString()
, 13 (,1375369309741
그러나 이는 순차적으로 업데이트되는 숫자이기 때문에(밀리초당 1회) 출력은 거의 항상 동일합니다.번 볼까요?
for (var i=0; i<10; i++) {
console.log((new Date()).valueOf().toString());
}
console.log("OMG so not random");
// 1375369431838
// 1375369431839
// 1375369431839
// 1375369431839
// 1375369431839
// 1375369431839
// 1375369431839
// 1375369431839
// 1375369431840
// 1375369431840
// OMG so not random
공정하게, 비교를 위해, 주어진 1분(후한 작업 실행 시간)에, 당신은 다음을 가질 것입니다.60*1000
아니면60000
특이한 점들
함의 함.Math.random
를 할 때,Math.random
수 있습니다.가 64 가 13 24 에서입니다.결과가 길수록 숫자가 많아져 엔트로피가 높아집니다.우선 어떤 길이가 가장 가능성이 높은지 알아봐야 합니다.
아래 스크립트를 통해 어떤 길이가 가장 가능성이 높은지 결정할 것입니다.를 생성하고다 100합니다..length
각각의 숫자의
// get distribution
var counts = [], rand, len;
for (var i=0; i<1000000; i++) {
rand = Math.random();
len = String(rand).length;
if (counts[len] === undefined) counts[len] = 0;
counts[len] += 1;
}
// calculate % frequency
var freq = counts.map(function(n) { return n/1000000 *100 });
각 를 100 에서 수 있습니다.Math.random
.
len frequency(%)
------------------
13 0.0004
14 0.0066
15 0.0654
16 0.6768
17 6.6703
18 61.133 <- highest probability
19 28.089 <- second highest probability
20 3.0287
21 0.2989
22 0.0262
23 0.0040
24 0.0004
비록 의 랜덤 하자, , 19 ,0.1234567890123456789
. . .0
그리고..
로 17명의 만 수 .이것은 우리에게 남습니다.10^17
+1
한 경우하면)0
; 아래 참고사항 참조) 또는 100,000,000,000,000,000,0001개의 고유사항을 참조하십시오.
그렇다면 얼마나 많은 임의의 입력을 생성할 수 있습니까?
와 에 Math.random
100,000,000,000,000,001 (Math.random)
* 60,000 (timestamp)
-----------------------------
6,000,000,000,000,000,060,000
그건 6,000,000,000,000,000,060,000 변의 다이입니다.또는, 이 숫자를 인간이 소화할 수 있도록 하기 위해, 이것은 대략 다음과 같은 숫자입니다.
input outputs
------------------------------------------------------------------------------
( 1×) 6,000,000,000,000,000,060,000-sided die 6,000,000,000,000,000,060,000
(28×) 6-sided die 6,140,942,214,464,815,497,21
(72×) 2-sided coins 4,722,366,482,869,645,213,696
꽤 괜찮은 것 같네요, 그렇죠? 그럼...
SHA1은 20바이트 값을 생성하며 256^20의 결과를 얻을 수 있습니다.따라서 SHA1을 최대한 활용하지 않고 있습니다.그럼 우리는 얼마나 사용하나요?
node> 6000000000000000060000 / Math.pow(256,20) * 100
1밀리초 타임스탬프와 Math.random은 SHA1의 160비트 잠재량의 4.11e-27%만을 사용합니다.
generator sha1 potential used
-----------------------------------------------------------------------------
crypto.randomBytes(20) 100%
Date() + Math.random() 0.00000000000000000000000000411%
6-sided die 0.000000000000000000000000000000000000000000000411%
A coin 0.000000000000000000000000000000000000000000000137%
세상에! 저좀 요.저 영점들 좀 봐요.요가 요?crypto.randomBytes(20)
? 243,583,606,221,817,150,598,111,409배 향상
에 대한 +1
0와 0.
에 이.+1
합니다.Math.random
답례하다, 답례를 하다0
그 말은 우리가 설명해야 할 독특한 결과가 하나 더 있다는 뜻입니다.
을 바탕으로 에 에0
올라올 겁니다.다.random_zero.js
, 자료를 좀 얻기 위해 만들었습니다.
#!/usr/bin/env node
var count = 0;
while (Math.random() !== 0) count++;
console.log(count);
그런 다음 4개의 스레드(4-core processor 있음)로 실행하여 출력을 파일에 추가했습니다.
$ yes | xargs -n 1 -P 4 node random_zero.js >> zeroes.txt
A 0
그렇게 어렵지는 않습니다.100개의 값이 기록된 후, 평균은
3분의 1, 164, 854,823개의 무작위는 0입니다.
이요 의한 분포와 더 많은 가 필요할 입니다. 가 v8 의입니다.Math.random
.
여기를 확인해 보십시오.node.js Crypto를 사용하여 HMAC-SHA1 해시를 생성하는 방법은 무엇입니까?해시 고유성을 보장하기 위해 현재 타임스탬프의 해시 + 랜덤 숫자를 만듭니다.
var current_date = (new Date()).valueOf().toString();
var random = Math.random().toString();
crypto.createHash('sha1').update(current_date + random).digest('hex');
브라우저에서도 해보세요!
편집: 이것은 제 이전 답변의 흐름에 잘 맞지 않았습니다.브라우저에서 이 작업을 수행할 수 있는 사용자를 위한 두 번째 답변으로 남겨둡니다.
당신이 원한다면 현대 브라우저에서 이 클라이언트 쪽을 할 수 있습니다.
// str byteToHex(uint8 byte)
// converts a single byte to a hex string
function byteToHex(byte) {
return ('0' + byte.toString(16)).slice(-2);
}
// str generateId(int len);
// len - must be an even number (default: 40)
function generateId(len = 40) {
var arr = new Uint8Array(len / 2);
window.crypto.getRandomValues(arr);
return Array.from(arr, byteToHex).join("");
}
console.log(generateId())
// "1e6ef8d5c851a3b5c5ad78f96dd086e4a77da800"
console.log(generateId(20))
// "d2180620d8f781178840"
브라우저 요구사항
Browser Minimum Version
--------------------------
Chrome 11.0
Firefox 21.0
IE 11.0
Opera 15.0
Safari 5.1
고유 식별자를 얻고 싶다면 UUID(Universally Unique Identifier) / GUID(Global Unique Identifier)를 사용해야 합니다.
해시는 어떤 크기의 입력을 위해서도 결정론적이고 고유하며 고정된 길이여야 합니다.따라서 해시 함수를 몇 번 실행해도 동일한 입력을 사용하면 출력은 동일합니다.
UUID는 고유하고 임의로 생성됩니다!'uuid'라는 패키지가 있습니다. npm을 통해 설치할 수 있습니다.
npm 설치 uuid
& 코드에서 모듈을 다음과 같이 가져옵니다.
const {v4:uuidv4} = required ('uuid')
// Method uuidv4를 호출하거나 불러오는 동안 이름을 지정하거나 저장하거나 할당합니다.메서드는 문자열 형태의 UUID를 반환합니다.
console.log(uuuidv4()); // 출력 예시 : '59594fc8-6a35-4f50-a966-4d735d8402ea'
npm 링크(필요하시면) : https://www.npmjs.com/package/uuid
으로.crypto
이지만,다를 할 수 .bcrypt
정말 강력하고 안전한 해시를 만들고 싶다면요.나는 그것을 비밀번호를 위해 사용합니다. 그것은 해싱, 소금 만들기, 비밀번호 비교를 위한 많은 기술들을 가지고 있습니다.
테크닉 1 (별도 함수 호출 시 솔트 및 해시 생성)
const salt = bcrypt.genSaltSync(saltRounds);
const hash = bcrypt.hashSync(myPlaintextPassword, salt);
테크닉 2 (자동 유전자 염 및 해시):
const hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
자세한 예는 여기에서 확인할 수 있습니다: https://www.npmjs.com/package/bcrypt
언급URL : https://stackoverflow.com/questions/9407892/how-to-generate-random-sha1-hash-to-use-as-id-in-node-js
'source' 카테고리의 다른 글
C++ 네임스페이스 안에 외부 "C" 링크가 있습니까? (0) | 2023.10.14 |
---|---|
다트의 AngularJS 스타일 프로그래밍? (0) | 2023.10.14 |
끝에 새 줄 문자를 붙이지 않고 pl/sql을 사용하여 문자열을 인쇄하는 방법 (0) | 2023.10.14 |
오류 메시지와 함께 SQL 쿼리에 대한 도움이 필요합니다. Operand에는 열 1개가 포함되어야 합니다. (0) | 2023.10.14 |
자바스크립트를 이용하여 Ctrl+V, Ctrl+C를 검출하는 방법? (0) | 2023.10.14 |