[{"data":1,"prerenderedAt":1053},["ShallowReactive",2],{"guide-cryptographic-vs-pseudo-random-numbers":3},{"id":4,"title":5,"body":6,"date":1042,"description":1043,"extension":1044,"meta":1045,"navigation":164,"path":1049,"readingTime":161,"seo":1050,"stem":1051,"__hash__":1052},"guides\u002Fguides\u002Fcryptographic-vs-pseudo-random-numbers.md","Cryptographic vs Pseudo-Random Numbers: When Security Matters",{"type":7,"value":8,"toc":1027},"minimark",[9,14,28,31,34,41,45,52,188,191,198,202,205,227,234,301,304,419,423,548,554,558,563,712,718,722,789,793,933,937,940,960,963,967,990,994,1003,1007,1023],[10,11,13],"h2",{"id":12},"two-kinds-of-random","Two Kinds of Random",[15,16,17,18,22,23,27],"p",{},"Computers cannot produce true randomness — they are deterministic machines. Instead, they use algorithms to generate sequences that ",[19,20,21],"em",{},"look"," random. These are called ",[24,25,26],"strong",{},"pseudo-random number generators"," (PRNGs).",[15,29,30],{},"For most applications, pseudo-randomness is fine. Shuffling a playlist, picking a background color, or generating test data — the output just needs to be unpredictable, not unbreakable.",[15,32,33],{},"But when security depends on the randomness — passwords, encryption keys, session tokens — pseudo-randomness is dangerous. An attacker who understands the PRNG state can predict future outputs.",[15,35,36,37,40],{},"That is where ",[24,38,39],{},"cryptographically secure pseudo-random number generators"," (CSPRNGs) come in.",[10,42,44],{"id":43},"how-prngs-work","How PRNGs Work",[15,46,47,48,51],{},"A PRNG starts from a ",[24,49,50],{},"seed"," value and applies a deterministic algorithm to produce a sequence. The same seed always produces the same sequence.",[53,54,59],"pre",{"className":55,"code":56,"language":57,"meta":58,"style":58},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F Simple PRNG: Linear Congruential Generator (illustrative only)\nlet seed = 12345;\nfunction lcg() {\n  seed = (seed * 1103515245 + 12345) & 0x7fffffff;\n  return seed \u002F 0x7fffffff;\n}\n\nlcg(); \u002F\u002F 0.5823...\nlcg(); \u002F\u002F 0.1267...\n","javascript","",[60,61,62,71,92,105,138,153,159,166,178],"code",{"__ignoreMap":58},[63,64,67],"span",{"class":65,"line":66},"line",1,[63,68,70],{"class":69},"sJ8bj","\u002F\u002F Simple PRNG: Linear Congruential Generator (illustrative only)\n",[63,72,74,78,82,85,89],{"class":65,"line":73},2,[63,75,77],{"class":76},"szBVR","let",[63,79,81],{"class":80},"sVt8B"," seed ",[63,83,84],{"class":76},"=",[63,86,88],{"class":87},"sj4cs"," 12345",[63,90,91],{"class":80},";\n",[63,93,95,98,102],{"class":65,"line":94},3,[63,96,97],{"class":76},"function",[63,99,101],{"class":100},"sScJk"," lcg",[63,103,104],{"class":80},"() {\n",[63,106,108,111,113,116,119,122,125,127,130,133,136],{"class":65,"line":107},4,[63,109,110],{"class":80},"  seed ",[63,112,84],{"class":76},[63,114,115],{"class":80}," (seed ",[63,117,118],{"class":76},"*",[63,120,121],{"class":87}," 1103515245",[63,123,124],{"class":76}," +",[63,126,88],{"class":87},[63,128,129],{"class":80},") ",[63,131,132],{"class":76},"&",[63,134,135],{"class":87}," 0x7fffffff",[63,137,91],{"class":80},[63,139,141,144,146,149,151],{"class":65,"line":140},5,[63,142,143],{"class":76},"  return",[63,145,81],{"class":80},[63,147,148],{"class":76},"\u002F",[63,150,135],{"class":87},[63,152,91],{"class":80},[63,154,156],{"class":65,"line":155},6,[63,157,158],{"class":80},"}\n",[63,160,162],{"class":65,"line":161},7,[63,163,165],{"emptyLinePlaceholder":164},true,"\n",[63,167,169,172,175],{"class":65,"line":168},8,[63,170,171],{"class":100},"lcg",[63,173,174],{"class":80},"(); ",[63,176,177],{"class":69},"\u002F\u002F 0.5823...\n",[63,179,181,183,185],{"class":65,"line":180},9,[63,182,171],{"class":100},[63,184,174],{"class":80},[63,186,187],{"class":69},"\u002F\u002F 0.1267...\n",[15,189,190],{},"If you know the seed and the algorithm, you can reproduce every number — past and future. This predictability is the fundamental weakness.",[15,192,193,194,197],{},"JavaScript's ",[60,195,196],{},"Math.random()"," is a PRNG. The exact algorithm varies by browser (V8 uses xorshift128+), but all share the same property: not cryptographically secure.",[10,199,201],{"id":200},"how-csprngs-differ","How CSPRNGs Differ",[15,203,204],{},"A CSPRNG adds three properties on top of statistical randomness:",[206,207,208,215,221],"ol",{},[209,210,211,214],"li",{},[24,212,213],{},"Next-bit unpredictability",": Given all previous outputs, the next bit cannot be predicted with probability better than 50%",[209,216,217,220],{},[24,218,219],{},"Backtracking resistance",": Even if the internal state is compromised, previous outputs cannot be reconstructed",[209,222,223,226],{},[24,224,225],{},"Entropy harvesting",": The generator collects randomness from hardware or OS events (timing, thermal noise, mouse movements) to seed itself",[15,228,229,230,233],{},"In JavaScript, the CSPRNG is ",[60,231,232],{},"crypto.getRandomValues()",":",[53,235,237],{"className":55,"code":236,"language":57,"meta":58,"style":58},"\u002F\u002F Cryptographically secure random bytes\nconst array = new Uint32Array(1);\ncrypto.getRandomValues(array);\nconsole.log(array[0]); \u002F\u002F Unpredictable, even to an attacker\n",[60,238,239,244,270,281],{"__ignoreMap":58},[63,240,241],{"class":65,"line":66},[63,242,243],{"class":69},"\u002F\u002F Cryptographically secure random bytes\n",[63,245,246,249,252,255,258,261,264,267],{"class":65,"line":73},[63,247,248],{"class":76},"const",[63,250,251],{"class":87}," array",[63,253,254],{"class":76}," =",[63,256,257],{"class":76}," new",[63,259,260],{"class":100}," Uint32Array",[63,262,263],{"class":80},"(",[63,265,266],{"class":87},"1",[63,268,269],{"class":80},");\n",[63,271,272,275,278],{"class":65,"line":94},[63,273,274],{"class":80},"crypto.",[63,276,277],{"class":100},"getRandomValues",[63,279,280],{"class":80},"(array);\n",[63,282,283,286,289,292,295,298],{"class":65,"line":107},[63,284,285],{"class":80},"console.",[63,287,288],{"class":100},"log",[63,290,291],{"class":80},"(array[",[63,293,294],{"class":87},"0",[63,296,297],{"class":80},"]); ",[63,299,300],{"class":69},"\u002F\u002F Unpredictable, even to an attacker\n",[15,302,303],{},"In Node.js:",[53,305,307],{"className":55,"code":306,"language":57,"meta":58,"style":58},"const crypto = require('crypto');\n\n\u002F\u002F Secure random bytes\nconst bytes = crypto.randomBytes(32);\nconsole.log(bytes.toString('hex'));\n\n\u002F\u002F Secure random integer in range\nconst n = crypto.randomInt(1, 101); \u002F\u002F 1 to 100 inclusive\n",[60,308,309,329,333,338,360,380,384,389],{"__ignoreMap":58},[63,310,311,313,316,318,321,323,327],{"class":65,"line":66},[63,312,248],{"class":76},[63,314,315],{"class":87}," crypto",[63,317,254],{"class":76},[63,319,320],{"class":100}," require",[63,322,263],{"class":80},[63,324,326],{"class":325},"sZZnC","'crypto'",[63,328,269],{"class":80},[63,330,331],{"class":65,"line":73},[63,332,165],{"emptyLinePlaceholder":164},[63,334,335],{"class":65,"line":94},[63,336,337],{"class":69},"\u002F\u002F Secure random bytes\n",[63,339,340,342,345,347,350,353,355,358],{"class":65,"line":107},[63,341,248],{"class":76},[63,343,344],{"class":87}," bytes",[63,346,254],{"class":76},[63,348,349],{"class":80}," crypto.",[63,351,352],{"class":100},"randomBytes",[63,354,263],{"class":80},[63,356,357],{"class":87},"32",[63,359,269],{"class":80},[63,361,362,364,366,369,372,374,377],{"class":65,"line":140},[63,363,285],{"class":80},[63,365,288],{"class":100},[63,367,368],{"class":80},"(bytes.",[63,370,371],{"class":100},"toString",[63,373,263],{"class":80},[63,375,376],{"class":325},"'hex'",[63,378,379],{"class":80},"));\n",[63,381,382],{"class":65,"line":155},[63,383,165],{"emptyLinePlaceholder":164},[63,385,386],{"class":65,"line":161},[63,387,388],{"class":69},"\u002F\u002F Secure random integer in range\n",[63,390,391,393,396,398,400,403,405,407,410,413,416],{"class":65,"line":168},[63,392,248],{"class":76},[63,394,395],{"class":87}," n",[63,397,254],{"class":76},[63,399,349],{"class":80},[63,401,402],{"class":100},"randomInt",[63,404,263],{"class":80},[63,406,266],{"class":87},[63,408,409],{"class":80},", ",[63,411,412],{"class":87},"101",[63,414,415],{"class":80},"); ",[63,417,418],{"class":69},"\u002F\u002F 1 to 100 inclusive\n",[10,420,422],{"id":421},"when-to-use-each","When to Use Each",[424,425,426,442],"table",{},[427,428,429],"thead",{},[430,431,432,436,439],"tr",{},[433,434,435],"th",{},"Use Case",[433,437,438],{},"Generator",[433,440,441],{},"Why",[443,444,445,457,467,477,487,498,508,518,528,538],"tbody",{},[430,446,447,451,454],{},[448,449,450],"td",{},"UI animations, delays",[448,452,453],{},"PRNG",[448,455,456],{},"No security impact",[430,458,459,462,464],{},[448,460,461],{},"Shuffling playlist",[448,463,453],{},[448,465,466],{},"No attacker motivation",[430,468,469,472,474],{},[448,470,471],{},"Dice rolls in casual games",[448,473,453],{},[448,475,476],{},"Low stakes",[430,478,479,482,484],{},[448,480,481],{},"Test data generation",[448,483,453],{},[448,485,486],{},"Speed matters more than security",[430,488,489,492,495],{},[448,490,491],{},"Password generation",[448,493,494],{},"CSPRNG",[448,496,497],{},"Predictable passwords get cracked",[430,499,500,503,505],{},[448,501,502],{},"Session tokens",[448,504,494],{},[448,506,507],{},"Predictable tokens enable hijacking",[430,509,510,513,515],{},[448,511,512],{},"Encryption keys",[448,514,494],{},[448,516,517],{},"Keys must be unguessable",[430,519,520,523,525],{},[448,521,522],{},"Nonces in protocols",[448,524,494],{},[448,526,527],{},"Replay attacks if predictable",[430,529,530,533,535],{},[448,531,532],{},"Lottery\u002Fprize draws",[448,534,494],{},[448,536,537],{},"Financial stakes",[430,539,540,543,545],{},[448,541,542],{},"Online gambling",[448,544,494],{},[448,546,547],{},"Regulatory requirement",[15,549,550,553],{},[24,551,552],{},"Rule of thumb",": If knowing the random value would let an attacker cause harm, use a CSPRNG.",[10,555,557],{"id":556},"practical-vulnerability-examples","Practical Vulnerability Examples",[559,560,562],"h3",{"id":561},"predictable-session-tokens","Predictable Session Tokens",[53,564,566],{"className":55,"code":565,"language":57,"meta":58,"style":58},"\u002F\u002F ❌ Vulnerable: predictable session token\nconst token = Math.random().toString(36).slice(2);\n\n\u002F\u002F ✅ Secure: unpredictable session token\nconst token = Array.from(crypto.getRandomValues(new Uint8Array(32)))\n  .map(b => b.toString(16).padStart(2, '0'))\n  .join('');\n",[60,567,568,573,611,615,620,654,698],{"__ignoreMap":58},[63,569,570],{"class":65,"line":66},[63,571,572],{"class":69},"\u002F\u002F ❌ Vulnerable: predictable session token\n",[63,574,575,577,580,582,585,588,591,593,595,598,601,604,606,609],{"class":65,"line":73},[63,576,248],{"class":76},[63,578,579],{"class":87}," token",[63,581,254],{"class":76},[63,583,584],{"class":80}," Math.",[63,586,587],{"class":100},"random",[63,589,590],{"class":80},"().",[63,592,371],{"class":100},[63,594,263],{"class":80},[63,596,597],{"class":87},"36",[63,599,600],{"class":80},").",[63,602,603],{"class":100},"slice",[63,605,263],{"class":80},[63,607,608],{"class":87},"2",[63,610,269],{"class":80},[63,612,613],{"class":65,"line":94},[63,614,165],{"emptyLinePlaceholder":164},[63,616,617],{"class":65,"line":107},[63,618,619],{"class":69},"\u002F\u002F ✅ Secure: unpredictable session token\n",[63,621,622,624,626,628,631,634,637,639,641,644,647,649,651],{"class":65,"line":140},[63,623,248],{"class":76},[63,625,579],{"class":87},[63,627,254],{"class":76},[63,629,630],{"class":80}," Array.",[63,632,633],{"class":100},"from",[63,635,636],{"class":80},"(crypto.",[63,638,277],{"class":100},[63,640,263],{"class":80},[63,642,643],{"class":76},"new",[63,645,646],{"class":100}," Uint8Array",[63,648,263],{"class":80},[63,650,357],{"class":87},[63,652,653],{"class":80},")))\n",[63,655,656,659,662,664,668,671,674,676,678,681,683,686,688,690,692,695],{"class":65,"line":155},[63,657,658],{"class":80},"  .",[63,660,661],{"class":100},"map",[63,663,263],{"class":80},[63,665,667],{"class":666},"s4XuR","b",[63,669,670],{"class":76}," =>",[63,672,673],{"class":80}," b.",[63,675,371],{"class":100},[63,677,263],{"class":80},[63,679,680],{"class":87},"16",[63,682,600],{"class":80},[63,684,685],{"class":100},"padStart",[63,687,263],{"class":80},[63,689,608],{"class":87},[63,691,409],{"class":80},[63,693,694],{"class":325},"'0'",[63,696,697],{"class":80},"))\n",[63,699,700,702,705,707,710],{"class":65,"line":161},[63,701,658],{"class":80},[63,703,704],{"class":100},"join",[63,706,263],{"class":80},[63,708,709],{"class":325},"''",[63,711,269],{"class":80},[15,713,714,715,717],{},"If an attacker observes a few ",[60,716,196],{}," outputs, they can reconstruct the internal state and predict all future tokens — including tokens assigned to other users.",[559,719,721],{"id":720},"password-reset-links","Password Reset Links",[53,723,725],{"className":55,"code":724,"language":57,"meta":58,"style":58},"\u002F\u002F ❌ Vulnerable: guessable reset code\nconst code = Math.floor(Math.random() * 1000000);\n\n\u002F\u002F ✅ Secure: unguessable reset code\nconst code = crypto.randomInt(1000000);\n",[60,726,727,732,761,765,770],{"__ignoreMap":58},[63,728,729],{"class":65,"line":66},[63,730,731],{"class":69},"\u002F\u002F ❌ Vulnerable: guessable reset code\n",[63,733,734,736,739,741,743,746,749,751,754,756,759],{"class":65,"line":73},[63,735,248],{"class":76},[63,737,738],{"class":87}," code",[63,740,254],{"class":76},[63,742,584],{"class":80},[63,744,745],{"class":100},"floor",[63,747,748],{"class":80},"(Math.",[63,750,587],{"class":100},[63,752,753],{"class":80},"() ",[63,755,118],{"class":76},[63,757,758],{"class":87}," 1000000",[63,760,269],{"class":80},[63,762,763],{"class":65,"line":94},[63,764,165],{"emptyLinePlaceholder":164},[63,766,767],{"class":65,"line":107},[63,768,769],{"class":69},"\u002F\u002F ✅ Secure: unguessable reset code\n",[63,771,772,774,776,778,780,782,784,787],{"class":65,"line":140},[63,773,248],{"class":76},[63,775,738],{"class":87},[63,777,254],{"class":76},[63,779,349],{"class":80},[63,781,402],{"class":100},[63,783,263],{"class":80},[63,785,786],{"class":87},"1000000",[63,788,269],{"class":80},[559,790,792],{"id":791},"race-condition-in-async-random","Race Condition in Async Random",[53,794,796],{"className":55,"code":795,"language":57,"meta":58,"style":58},"\u002F\u002F ❌ Problematic: two calls may get related values\nconst a = await crypto.getRandomValues(new Uint8Array(16));\nconst b = await crypto.getRandomValues(new Uint8Array(16));\n\n\u002F\u002F ✅ Better: get all randomness in one call\nconst both = crypto.getRandomValues(new Uint8Array(32));\nconst a = both.slice(0, 16);\nconst b = both.slice(16);\n",[60,797,798,803,831,858,862,867,892,915],{"__ignoreMap":58},[63,799,800],{"class":65,"line":66},[63,801,802],{"class":69},"\u002F\u002F ❌ Problematic: two calls may get related values\n",[63,804,805,807,810,812,815,817,819,821,823,825,827,829],{"class":65,"line":73},[63,806,248],{"class":76},[63,808,809],{"class":87}," a",[63,811,254],{"class":76},[63,813,814],{"class":76}," await",[63,816,349],{"class":80},[63,818,277],{"class":100},[63,820,263],{"class":80},[63,822,643],{"class":76},[63,824,646],{"class":100},[63,826,263],{"class":80},[63,828,680],{"class":87},[63,830,379],{"class":80},[63,832,833,835,838,840,842,844,846,848,850,852,854,856],{"class":65,"line":94},[63,834,248],{"class":76},[63,836,837],{"class":87}," b",[63,839,254],{"class":76},[63,841,814],{"class":76},[63,843,349],{"class":80},[63,845,277],{"class":100},[63,847,263],{"class":80},[63,849,643],{"class":76},[63,851,646],{"class":100},[63,853,263],{"class":80},[63,855,680],{"class":87},[63,857,379],{"class":80},[63,859,860],{"class":65,"line":107},[63,861,165],{"emptyLinePlaceholder":164},[63,863,864],{"class":65,"line":140},[63,865,866],{"class":69},"\u002F\u002F ✅ Better: get all randomness in one call\n",[63,868,869,871,874,876,878,880,882,884,886,888,890],{"class":65,"line":155},[63,870,248],{"class":76},[63,872,873],{"class":87}," both",[63,875,254],{"class":76},[63,877,349],{"class":80},[63,879,277],{"class":100},[63,881,263],{"class":80},[63,883,643],{"class":76},[63,885,646],{"class":100},[63,887,263],{"class":80},[63,889,357],{"class":87},[63,891,379],{"class":80},[63,893,894,896,898,900,903,905,907,909,911,913],{"class":65,"line":161},[63,895,248],{"class":76},[63,897,809],{"class":87},[63,899,254],{"class":76},[63,901,902],{"class":80}," both.",[63,904,603],{"class":100},[63,906,263],{"class":80},[63,908,294],{"class":87},[63,910,409],{"class":80},[63,912,680],{"class":87},[63,914,269],{"class":80},[63,916,917,919,921,923,925,927,929,931],{"class":65,"line":168},[63,918,248],{"class":76},[63,920,837],{"class":87},[63,922,254],{"class":76},[63,924,902],{"class":80},[63,926,603],{"class":100},[63,928,263],{"class":80},[63,930,680],{"class":87},[63,932,269],{"class":80},[10,934,936],{"id":935},"performance-comparison","Performance Comparison",[15,938,939],{},"CSPRNGs are slower because they must read from the operating system's entropy pool:",[53,941,943],{"className":55,"code":942,"language":57,"meta":58,"style":58},"\u002F\u002F Benchmark: 1 million random numbers\n\u002F\u002F Math.random():              ~50ms\n\u002F\u002F crypto.getRandomValues():   ~200ms\n",[60,944,945,950,955],{"__ignoreMap":58},[63,946,947],{"class":65,"line":66},[63,948,949],{"class":69},"\u002F\u002F Benchmark: 1 million random numbers\n",[63,951,952],{"class":65,"line":73},[63,953,954],{"class":69},"\u002F\u002F Math.random():              ~50ms\n",[63,956,957],{"class":65,"line":94},[63,958,959],{"class":69},"\u002F\u002F crypto.getRandomValues():   ~200ms\n",[15,961,962],{},"The 4–5x slowdown is the cost of security. For most applications, this is negligible — you are not generating a million tokens per second.",[10,964,966],{"id":965},"key-takeaways","Key Takeaways",[968,969,970,973,978,981,984,987],"ul",{},[209,971,972],{},"PRNGs are deterministic algorithms — same seed produces same sequence",[209,974,975,977],{},[60,976,196],{}," is a PRNG and is never safe for security-critical randomness",[209,979,980],{},"CSPRNGs harvest hardware entropy and resist prediction even if state is compromised",[209,982,983],{},"Use CSPRNGs for passwords, tokens, keys, nonces, and anything with financial stakes",[209,985,986],{},"Use PRNGs for animations, shuffling, test data, and non-security contexts",[209,988,989],{},"The performance cost of CSPRNGs is negligible for typical web application loads",[10,991,993],{"id":992},"try-it-yourself","Try It Yourself",[15,995,996,997,1002],{},"Generate secure random numbers with customizable ranges and precision using our ",[998,999,1001],"a",{"href":1000},"\u002Ftools\u002Frandom-number","Random Number Generator",". Choose between integer, decimal, and unique-value modes for any use case.",[10,1004,1006],{"id":1005},"related-guides","Related Guides",[968,1008,1009,1016],{},[209,1010,1011,1015],{},[998,1012,1014],{"href":1013},"\u002Fguides\u002Frandom-number-guide","Random Number Guide"," — how random number generators work in computing",[209,1017,1018,1022],{},[998,1019,1021],{"href":1020},"\u002Fguides\u002Frandomness-in-programming","Randomness in Programming"," — statistical properties and common distributions",[1024,1025,1026],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":58,"searchDepth":73,"depth":73,"links":1028},[1029,1030,1031,1032,1033,1038,1039,1040,1041],{"id":12,"depth":73,"text":13},{"id":43,"depth":73,"text":44},{"id":200,"depth":73,"text":201},{"id":421,"depth":73,"text":422},{"id":556,"depth":73,"text":557,"children":1034},[1035,1036,1037],{"id":561,"depth":94,"text":562},{"id":720,"depth":94,"text":721},{"id":791,"depth":94,"text":792},{"id":935,"depth":73,"text":936},{"id":965,"depth":73,"text":966},{"id":992,"depth":73,"text":993},{"id":1005,"depth":73,"text":1006},"2026-05-28","Understand the difference between cryptographic and pseudo-random number generators. Learn when to use each type and why Math.random() is unsafe for security.","md",{"keywords":1046,"immutable":164},[1047,1048],"random-number","cryptographic-vs-pseudo-random-numbers","\u002Fguides\u002Fcryptographic-vs-pseudo-random-numbers",{"title":5,"description":1043},"guides\u002Fcryptographic-vs-pseudo-random-numbers","_s-82cunj5aBudyrw_5uN06nIMJlASv5tKXuiXzIBjU",1780401332587]