javascript - w3schools - কিভাবে node.js এ আইডি হিসাবে র্যান্ডম SHA1 হ্যাশ ব্যবহার করবেন?




w3schools javascript (2)

243,583,606,221,817,150,598,111,409x আরো এনট্রপি

আমি crypto.randomBytes ব্যবহার করে সুপারিশ চাই। এটি sha1 নয়, কিন্তু id উদ্দেশ্যে, এটি দ্রুত, এবং ঠিক যেমন "র্যান্ডম"।

var id = crypto.randomBytes(20).toString('hex');
//=> f26d60305dae929ef8640a75e70dd78ab809cfe9

ফলে স্ট্রিং আপনার দ্বারা উত্পন্ন র্যান্ডম বাইট হিসাবে দ্বিগুণ হবে; প্রতিটি বাইট হেক্স এনকোড করা 2 অক্ষর। 20 বাইট হ্যাক 40 অক্ষর হবে।

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 সহ) সর্বদা একই আউটপুট তৈরি করবে যদি একই ইনপুট দেওয়া হয়।

বলুন আমরা আইডি তৈরি করতে চাই কিন্তু আমাদের র্যান্ডম ইনপুট একটি মুদ্রা টস দ্বারা উত্পন্ন হয়। আমরা "heads" বা "tails"

% echo -n "heads" | shasum
c25dda249cdece9d908cc33adcd16aa05e20290f  -

% echo -n "tails" | shasum
71ac9eed6a76a285ae035fe84a251d56ae9485a4  -

যদি "heads" আবার আসে, তবে SHA1 আউটপুটটি প্রথমবারের মত একই হবে

% echo -n "heads" | shasum
c25dda249cdece9d908cc33adcd16aa05e20290f  -

ঠিক আছে, তাই একটি মুদ্রা টস একটি মহান এলোমেলো আইডি জেনারেটর না, কারণ আমরা শুধুমাত্র 2 সম্ভাব্য আউটপুট আছে।

আমরা যদি 6-পার্শ্বযুক্ত ময়দানের আদর্শ ব্যবহার করি তবে আমাদের 6 টি সম্ভাব্য ইনপুট রয়েছে। কতটা সম্ভব SHA1 আউটপুট? 6!

input => (sha1) => output
1 => 356a192b7913b04c54574d18c28d46e6395428ab
2 => da4b9237bacccdf19c0760cab7aec4a8359010b0
3 => 77de68daecd823babbb58edb1c8e14d7106e83bb
4 => 1b6453892473a467d07372d45eb05abc2031647a
5 => ac3478d69a3c81fa62e60f5c3696165a4e5e6ac4
6 => c1dfd96eea8cc2b62785275bca38ac261256e278

আমাদের ফাংশন আউটপুট খুব র্যান্ডম দেখায় , কারণ এটি খুব র্যান্ডম বলে মনে করে নিজেকে চিন্তিত করা সহজ।

আমরা উভয় সম্মত যে একটি মুদ্রা টস বা 6-পার্শ্বযুক্ত মরা একটি খারাপ র্যান্ডম আইডি জেনারেটর তৈরি করবে, কারণ আমাদের সম্ভাব্য SHA1 ফলাফল (আমরা যে আইডিটির জন্য ব্যবহার করি) খুব কম। কিন্তু যদি আমরা এমন কিছু ব্যবহার করি যা অনেক বেশি আউটপুট থাকে? মিলিসেকেন্ড সঙ্গে টাইমস্ট্যাম্প লেগেছে? অথবা জাভাস্ক্রিপ্ট এর Math.random ? নাকি এমন দুটি সংমিশ্রণ ?

আসুন আমরা কতটুকু অনন্য আইড পেতে পারি তা গণনা করা যাক ...

মিলিসেকেন্ড সঙ্গে একটি টাইমস্ট্যাম্প অনন্যতা

ব্যবহার করার সময় (new Date()).valueOf().toString() , আপনি একটি 13-অক্ষর নম্বর পেয়েছেন (উদাহরণস্বরূপ, 1375369309741 )। যাইহোক, যেহেতু এটি একটি ক্রমবর্ধমান আপডেট করা নম্বর (একবার মিলিসেকেন্ড প্রতি একবার), আউটপুট প্রায় সবসময় একই। একবার দেখা যাক

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

তুলনামূলক উদ্দেশ্যে, তুলনামূলক উদ্দেশ্যে, একটি নির্দিষ্ট মিনিটে (উদার ক্রিয়াকলাপ কার্যকর সময়), আপনার 60*1000 বা 60000 60*1000 থাকবে।

Math.random এর অনন্যতা

এখন, যখন জাভাস্ক্রিপ্ট 64-বিট ভাসমান বিন্দু সংখ্যার প্রতিনিধিত্ব করে, তখন Math.random ব্যবহার করার সময়, আপনি 13 এবং 24 অক্ষরের লম্বা লম্বা লম্বা নম্বর পাবেন। একটি দীর্ঘ ফলাফল মানে আরো ডিজিট মানে আরো এনট্রপি। প্রথম, আমাদের সবচেয়ে সম্ভাব্য দৈর্ঘ্য খুঁজে বের করতে হবে।

নীচের স্ক্রিপ্ট সবচেয়ে দৈর্ঘ্য যা দৈর্ঘ্য নির্ধারণ করবে। আমরা 1 মিলিয়ন র্যান্ডম সংখ্যা জেনারেট করে এবং প্রতিটি নম্বরের .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 });

প্রতিটি কাউন্টারকে 1 মিলিয়ন ভাগ করে বিভক্ত করে, আমরা Math.random থেকে Math.random নম্বরের দৈর্ঘ্যের সম্ভাবনাটি 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,001 টি ইউনিক দিয়ে ছেড়ে দেয়।

তাই আমরা কত র্যান্ডম ইনপুট তৈরি করতে পারি?

ঠিক আছে, আমরা মিলিসেকেন্ড টাইমস্ট্যাম্প এবং Math.random এর ফলাফলগুলির সংখ্যা গণনা Math.random

      100,000,000,000,000,001 (Math.random)
*                      60,000 (timestamp)
-----------------------------
6,000,000,000,000,000,060,000

এটি একটি একক 6,00,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 একটি সম্ভাব্য 256 ^ 20 ফলাফল সহ 20-বাইট মান উত্পন্ন করে। তাই আমরা সত্যিই সম্পূর্ণ সম্ভাবনা থেকে SHA1 ব্যবহার করছি না। ভাল আমরা কত ব্যবহার করছেন?

node> 6000000000000000060000 / Math.pow(256,20) * 100

একটি মিলিসকন্ড টাইমস্ট্যাম্প এবং 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 এবং জিরো ফ্রিকোয়েন্সি সম্পর্কে নোট

যদি আপনি +1 সম্পর্কে অবাক হয়ে থাকেন, তবে Math.random জন্য একটি 0 সম্ভব। এর অর্থ হল আরো 1 টি সম্ভাব্য অনন্য ফলাফলের জন্য আমাদের অ্যাকাউন্ট আছে।

নীচের যে আলোচনার উপর ভিত্তি করে, আমি ফ্রিকোয়েন্সি সম্পর্কে অদ্ভুত ছিল একটি 0 আসা হবে। এখানে একটি ছোট স্ক্রিপ্ট, random_zero.js , আমি কিছু তথ্য পেতে তৈরি

#!/usr/bin/env node
var count = 0;
while (Math.random() !== 0) count++;
console.log(count);

তারপর, আমি এটি 4 টি থ্রেডে দৌড়েছি (আমার একটি 4-কোর প্রসেসর আছে), একটি ফাইলের আউটপুট যোগ করে

$ yes | xargs -n 1 -P 4 node random_zero.js >> zeroes.txt

তাই এটি সক্রিয় করে যে একটি 0 পেতে কঠিন নয়। 100 মান রেকর্ড করার পরে, গড় ছিল

3,164,854,823 র্যান্ডম একটি 0

কুল! আরো গবেষণাটি জানার দরকার হবে যে সেই নম্বরটি v8 এর Math.random প্রয়োগের অভিন্ন বন্টনের সাথে সমান্তরাল Math.random

আমি node.js এর জন্য sha1 id তৈরি করতে এই লাইনটি ব্যবহার করছি:

crypto.createHash('sha1').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





entropy