243,583,606,221,817,150,598,111,409x আরও এনট্রপি
আমি crypto.randomBytes ব্যবহার করার পরামর্শ দিই । এটি নয় sha1
, আইডি উদ্দেশ্যে, এটি দ্রুত এবং ঠিক "এলোমেলো"।
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 টি সম্ভাব্য ফলাফল রয়েছে, তাই প্রথম রোল যথেষ্ট।
কেন এই ভাল?
এটি আরও ভাল কেন তা বুঝতে, আমাদের প্রথমে হ্যাশিং ফাংশনগুলি কীভাবে কাজ করে তা বুঝতে হবে। হ্যাশিং ফাংশনগুলি (এসএএএ 1 সহ) সর্বদা একই আউটপুট উত্পন্ন করে যদি একই ইনপুট দেওয়া হয়।
বলুন আমরা আইডি জেনারেট করতে চাই তবে আমাদের এলোমেলো ইনপুটটি একটি কয়েন টস দ্বারা উত্পন্ন। আমাদের আছে "heads"
বা"tails"
% echo -n "heads" | shasum
c25dda249cdece9d908cc33adcd16aa05e20290f -
% echo -n "tails" | shasum
71ac9eed6a76a285ae035fe84a251d56ae9485a4 -
তাহলে "heads"
আবার আসে, SHA1 এ আউটপুট হবে একই হিসাবে এটি প্রথম সময় ছিল
% echo -n "heads" | shasum
c25dda249cdece9d908cc33adcd16aa05e20290f -
ঠিক আছে, সুতরাং একটি কয়েন টস দুর্দান্ত র্যান্ডম আইডি জেনারেটর নয় কারণ আমাদের কাছে কেবল দুটি সম্ভাব্য আউটপুট রয়েছে।
যদি আমরা একটি স্ট্যান্ডার্ড 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
অদ্ভুত হবে।
এর স্বতন্ত্রতা Math.random
এখন, ব্যবহার করার সময় Math.random
, জাভাস্ক্রিপ্ট যেভাবে flo৪-বিট ভাসমান পয়েন্ট সংখ্যা উপস্থাপন করে, আপনি 13 এবং 24 অক্ষরের মধ্যে দৈর্ঘ্যের দৈর্ঘ্যের সংখ্যা পাবেন get দীর্ঘ ফলাফলের অর্থ আরও বেশি অঙ্ক যার অর্থ আরও এনট্রপি। প্রথমত, আমাদের সর্বাধিক সম্ভাব্য দৈর্ঘ্যটি খুঁজে বের করতে হবে।
নীচের স্ক্রিপ্টটি নির্ধারণ করবে কোন দৈর্ঘ্যটি সবচেয়ে সম্ভাব্য। আমরা 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
।
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 টি অসুবিধায় ফেলেছে leaves
সুতরাং আমরা কত এলোমেলো ইনপুট তৈরি করতে পারি?
ঠিক আছে, আমরা মিলিসেকেন্ড টাইমস্ট্যাম্পের জন্য ফলাফলের সংখ্যা গণনা করেছি 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 একটি সম্ভাব্য 256 ^ 20 ফলাফল সহ 20-বাইট মান উত্পাদন করে। সুতরাং আমরা সত্যিই এটির সম্পূর্ণ সম্ভাবনার জন্য SHA1 ব্যবহার করছি না। আচ্ছা আমরা কতটা ব্যবহার করছি?
node> 6000000000000000060000 / Math.pow(256,20) * 100
একটি মিলিসেকেন্ড টাইমস্ট্যাম্প এবং ম্যাথ.রান্ডম 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 এলোমেলোতে 1 টি 0
শান্ত! এই সংখ্যাটি ভি 8 এর Math.random
বাস্তবায়নের অভিন্ন বিতরণের সাথে সমান কিনা তা জানতে আরও গবেষণার প্রয়োজন হবে