[{"data":1,"prerenderedAt":803},["ShallowReactive",2],{"guide-randomness-in-programming":3},{"id":4,"title":5,"body":6,"date":795,"description":796,"extension":797,"meta":798,"navigation":336,"path":799,"readingTime":649,"seo":800,"stem":801,"__hash__":802},"guides\u002Fguides\u002Frandomness-in-programming.md","Randomness in Programming",{"type":7,"value":8,"toc":775},"minimark",[9,14,27,30,34,41,46,49,60,71,77,81,92,102,106,113,145,151,155,158,162,212,219,223,275,279,301,316,320,355,366,370,483,487,607,611,614,653,659,672,676,718,722,748,752,771],[10,11,13],"h2",{"id":12},"what-is-randomness-in-code","What Is Randomness in Code?",[15,16,17,18,22,23,26],"p",{},"Randomness in programming falls into two categories: ",[19,20,21],"strong",{},"pseudo-random"," and ",[19,24,25],{},"cryptographically secure",". Most code you write uses pseudo-random number generators (PRNGs) — fast algorithms that produce sequences appearing random but are fully deterministic. Cryptographic randomness draws from hardware or OS entropy sources and is unpredictable even if you know the algorithm state.",[15,28,29],{},"Choosing the wrong type creates real problems. A PRNG in a password generator lets attackers predict credentials. A CSPRNG in a game simulation wastes CPU cycles for no security benefit.",[10,31,33],{"id":32},"how-prngs-work","How PRNGs Work",[15,35,36,37,40],{},"PRNGs start from a ",[19,38,39],{},"seed"," value and apply a mathematical formula to produce each output. Same seed, same sequence — every time. This determinism is useful for testing and reproducibility but disqualifies PRNGs from security contexts.",[42,43,45],"h3",{"id":44},"linear-congruential-generator-lcg","Linear Congruential Generator (LCG)",[15,47,48],{},"The oldest and simplest PRNG family. It computes each number as:",[50,51,56],"pre",{"className":52,"code":54,"language":55},[53],"language-text","next = (a * current + c) mod m\n","text",[57,58,54],"code",{"__ignoreMap":59},"",[15,61,62,63,66,67,70],{},"LCG powers ",[57,64,65],{},"java.util.Random"," and was the default in C's ",[57,68,69],{},"rand()",". It is fast but has poor statistical quality — low bits cycle in short periods, and the output forms a hyperplane pattern in multidimensional space.",[15,72,73,76],{},[19,74,75],{},"Use it for:"," trivial demos, never for serious work.",[42,78,80],{"id":79},"mersenne-twister-mt19937","Mersenne Twister (MT19937)",[15,82,83,84,87,88,91],{},"The most widely used PRNG. It has a period of 2¹⁹⁹³⁷−1 and passes most statistical tests. Python's ",[57,85,86],{},"random"," module, C++'s ",[57,89,90],{},"std::mt19937",", and Ruby's default all use Mersenne Twister.",[15,93,94,97,98,101],{},[19,95,96],{},"Drawbacks:"," its 2.5 KB state is large, it fails some modern statistical suites (TestU01 Big Crush), and it is ",[19,99,100],{},"not"," cryptographically secure. Observing 624 consecutive outputs lets you reconstruct the full state and predict all future values.",[42,103,105],{"id":104},"xoshiro-xorshift-family","xoshiro \u002F xorshift Family",[15,107,108,109,112],{},"Modern alternatives designed by Sebastiano Vigna. The xoshiro256** variant offers excellent statistical quality, small state (32 bytes), and high speed. It is the default PRNG in V8 (JavaScript), Rust's ",[57,110,111],{},"SmallRng",", and many game engines.",[50,114,118],{"className":115,"code":116,"language":117,"meta":59,"style":59},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F V8 uses xoshiro256** under the hood\nMath.random() \u002F\u002F → 0.4621848491...\n","javascript",[57,119,120,129],{"__ignoreMap":59},[121,122,125],"span",{"class":123,"line":124},"line",1,[121,126,128],{"class":127},"sJ8bj","\u002F\u002F V8 uses xoshiro256** under the hood\n",[121,130,132,136,139,142],{"class":123,"line":131},2,[121,133,135],{"class":134},"sVt8B","Math.",[121,137,86],{"class":138},"sScJk",[121,140,141],{"class":134},"() ",[121,143,144],{"class":127},"\u002F\u002F → 0.4621848491...\n",[15,146,147,150],{},[19,148,149],{},"Trade-off:"," like all PRNGs, xoshiro is predictable. If you need security, look elsewhere.",[10,152,154],{"id":153},"cryptographically-secure-prngs-csprngs","Cryptographically Secure PRNGs (CSPRNGs)",[15,156,157],{},"CSPRNGs pull entropy from the operating system — hardware noise, disk timings, keystroke intervals — and mix it into a pool. Even if an attacker observes previous outputs, they cannot predict future values.",[42,159,161],{"id":160},"browser-cryptogetrandomvalues","Browser: crypto.getRandomValues",[50,163,165],{"className":115,"code":164,"language":117,"meta":59,"style":59},"const array = new Uint32Array(4);\ncrypto.getRandomValues(array);\n\u002F\u002F → [2847936452, 1067498723, 3891746501, 723948102]\n",[57,166,167,195,206],{"__ignoreMap":59},[121,168,169,173,177,180,183,186,189,192],{"class":123,"line":124},[121,170,172],{"class":171},"szBVR","const",[121,174,176],{"class":175},"sj4cs"," array",[121,178,179],{"class":171}," =",[121,181,182],{"class":171}," new",[121,184,185],{"class":138}," Uint32Array",[121,187,188],{"class":134},"(",[121,190,191],{"class":175},"4",[121,193,194],{"class":134},");\n",[121,196,197,200,203],{"class":123,"line":131},[121,198,199],{"class":134},"crypto.",[121,201,202],{"class":138},"getRandomValues",[121,204,205],{"class":134},"(array);\n",[121,207,209],{"class":123,"line":208},3,[121,210,211],{"class":127},"\u002F\u002F → [2847936452, 1067498723, 3891746501, 723948102]\n",[15,213,214,215,218],{},"This is the only secure way to get random data in the browser. ",[57,216,217],{},"Math.random()"," is fast but predictable.",[42,220,222],{"id":221},"nodejs-cryptorandombytes","Node.js: crypto.randomBytes",[50,224,226],{"className":115,"code":225,"language":117,"meta":59,"style":59},"const crypto = require('crypto');\nconst bytes = crypto.randomBytes(16);\n\u002F\u002F → \u003CBuffer 7a 3f b2 ...>\n",[57,227,228,248,270],{"__ignoreMap":59},[121,229,230,232,235,237,240,242,246],{"class":123,"line":124},[121,231,172],{"class":171},[121,233,234],{"class":175}," crypto",[121,236,179],{"class":171},[121,238,239],{"class":138}," require",[121,241,188],{"class":134},[121,243,245],{"class":244},"sZZnC","'crypto'",[121,247,194],{"class":134},[121,249,250,252,255,257,260,263,265,268],{"class":123,"line":131},[121,251,172],{"class":171},[121,253,254],{"class":175}," bytes",[121,256,179],{"class":171},[121,258,259],{"class":134}," crypto.",[121,261,262],{"class":138},"randomBytes",[121,264,188],{"class":134},[121,266,267],{"class":175},"16",[121,269,194],{"class":134},[121,271,272],{"class":123,"line":208},[121,273,274],{"class":127},"\u002F\u002F → \u003CBuffer 7a 3f b2 ...>\n",[42,276,278],{"id":277},"python-secrets-module","Python: secrets Module",[50,280,284],{"className":281,"code":282,"language":283,"meta":59,"style":59},"language-python shiki shiki-themes github-light github-dark","import secrets\ntoken = secrets.token_hex(16)  # 32 hex chars\nnumber = secrets.randbelow(100)  # 0–99 inclusive\n","python",[57,285,286,291,296],{"__ignoreMap":59},[121,287,288],{"class":123,"line":124},[121,289,290],{},"import secrets\n",[121,292,293],{"class":123,"line":131},[121,294,295],{},"token = secrets.token_hex(16)  # 32 hex chars\n",[121,297,298],{"class":123,"line":208},[121,299,300],{},"number = secrets.randbelow(100)  # 0–99 inclusive\n",[15,302,303,304,307,308,311,312,315],{},"Python 3.6+ provides ",[57,305,306],{},"secrets"," specifically for security use cases. The older ",[57,309,310],{},"random.SystemRandom"," calls ",[57,313,314],{},"os.urandom"," under the hood.",[42,317,319],{"id":318},"java-securerandom","Java: SecureRandom",[50,321,325],{"className":322,"code":323,"language":324,"meta":59,"style":59},"language-java shiki shiki-themes github-light github-dark","import java.security.SecureRandom;\n\nSecureRandom sr = new SecureRandom();\nbyte[] bytes = new byte[16];\nsr.nextBytes(bytes);\n","java",[57,326,327,332,338,343,349],{"__ignoreMap":59},[121,328,329],{"class":123,"line":124},[121,330,331],{},"import java.security.SecureRandom;\n",[121,333,334],{"class":123,"line":131},[121,335,337],{"emptyLinePlaceholder":336},true,"\n",[121,339,340],{"class":123,"line":208},[121,341,342],{},"SecureRandom sr = new SecureRandom();\n",[121,344,346],{"class":123,"line":345},4,[121,347,348],{},"byte[] bytes = new byte[16];\n",[121,350,352],{"class":123,"line":351},5,[121,353,354],{},"sr.nextBytes(bytes);\n",[15,356,357,358,361,362,365],{},"On Linux, ",[57,359,360],{},"SecureRandom"," reads from ",[57,363,364],{},"\u002Fdev\u002Furandom"," by default. On Windows, it uses the CryptoAPI.",[10,367,369],{"id":368},"prng-vs-csprng-comparison","PRNG vs CSPRNG Comparison",[371,372,373,389],"table",{},[374,375,376],"thead",{},[377,378,379,383,386],"tr",{},[380,381,382],"th",{},"Property",[380,384,385],{},"PRNG (Math.random, random)",[380,387,388],{},"CSPRNG (crypto, secrets)",[390,391,392,406,419,432,445,458,471],"tbody",{},[377,393,394,400,403],{},[395,396,397],"td",{},[19,398,399],{},"Speed",[395,401,402],{},"Very fast",[395,404,405],{},"Slower (entropy mixing)",[377,407,408,413,416],{},[395,409,410],{},[19,411,412],{},"Predictability",[395,414,415],{},"Deterministic from seed",[395,417,418],{},"Unpredictable",[377,420,421,426,429],{},[395,422,423],{},[19,424,425],{},"State recovery",[395,427,428],{},"Possible from outputs",[395,430,431],{},"Computationationally infeasible",[377,433,434,439,442],{},[395,435,436],{},[19,437,438],{},"Period",[395,440,441],{},"Fixed (2¹⁹⁹³⁷ for MT)",[395,443,444],{},"No fixed period",[377,446,447,452,455],{},[395,448,449],{},[19,450,451],{},"Use for passwords",[395,453,454],{},"Never",[395,456,457],{},"Always",[377,459,460,465,468],{},[395,461,462],{},[19,463,464],{},"Use for simulations",[395,466,467],{},"Preferred",[395,469,470],{},"Overkill",[377,472,473,478,480],{},[395,474,475],{},[19,476,477],{},"Use for games",[395,479,467],{},[395,481,482],{},"Only for gambling",[10,484,486],{"id":485},"language-api-quick-reference","Language API Quick Reference",[371,488,489,502],{},[374,490,491],{},[377,492,493,496,499],{},[380,494,495],{},"Language",[380,497,498],{},"PRNG",[380,500,501],{},"CSPRNG",[390,503,504,520,537,553,570,587],{},[377,505,506,511,515],{},[395,507,508],{},[19,509,510],{},"JavaScript",[395,512,513],{},[57,514,217],{},[395,516,517],{},[57,518,519],{},"crypto.getRandomValues()",[377,521,522,527,532],{},[395,523,524],{},[19,525,526],{},"Python",[395,528,529],{},[57,530,531],{},"random.random()",[395,533,534],{},[57,535,536],{},"secrets.token_hex()",[377,538,539,544,548],{},[395,540,541],{},[19,542,543],{},"Java",[395,545,546],{},[57,547,65],{},[395,549,550],{},[57,551,552],{},"java.security.SecureRandom",[377,554,555,560,565],{},[395,556,557],{},[19,558,559],{},"Go",[395,561,562],{},[57,563,564],{},"math\u002Frand",[395,566,567],{},[57,568,569],{},"crypto\u002Frand",[377,571,572,577,582],{},[395,573,574],{},[19,575,576],{},"Rust",[395,578,579],{},[57,580,581],{},"rand::thread_rng()",[395,583,584],{},[57,585,586],{},"rand::rngs::OsRng",[377,588,589,594,602],{},[395,590,591],{},[19,592,593],{},"PHP",[395,595,596,598,599],{},[57,597,69],{}," \u002F ",[57,600,601],{},"mt_rand()",[395,603,604],{},[57,605,606],{},"random_bytes()",[10,608,610],{"id":609},"seeding-and-reproducibility","Seeding and Reproducibility",[15,612,613],{},"Controlling the seed gives you reproducible results — useful for tests, procedural content, and scientific experiments.",[50,615,617],{"className":281,"code":616,"language":283,"meta":59,"style":59},"import random\n\nrandom.seed(42)\nprint(random.random())  # 0.6394267984578837 — same every time\n\nrandom.seed(42)\nprint(random.random())  # 0.6394267984578837 — exact repeat\n",[57,618,619,624,628,633,638,642,647],{"__ignoreMap":59},[121,620,621],{"class":123,"line":124},[121,622,623],{},"import random\n",[121,625,626],{"class":123,"line":131},[121,627,337],{"emptyLinePlaceholder":336},[121,629,630],{"class":123,"line":208},[121,631,632],{},"random.seed(42)\n",[121,634,635],{"class":123,"line":345},[121,636,637],{},"print(random.random())  # 0.6394267984578837 — same every time\n",[121,639,640],{"class":123,"line":351},[121,641,337],{"emptyLinePlaceholder":336},[121,643,645],{"class":123,"line":644},6,[121,646,632],{},[121,648,650],{"class":123,"line":649},7,[121,651,652],{},"print(random.random())  # 0.6394267984578837 — exact repeat\n",[15,654,655,658],{},[19,656,657],{},"Warning:"," reusing the same seed in production is a security risk. If an attacker guesses your seed, they can reproduce your entire random sequence. Only seed PRNGs deliberately in testing or creative coding.",[15,660,661,662,664,665,667,668,671],{},"In JavaScript, ",[57,663,217],{}," does ",[19,666,100],{}," expose a seed API. For seeded randomness, use a library like ",[57,669,670],{},"seedrandom"," or implement xoshiro directly.",[10,673,675],{"id":674},"common-mistakes","Common Mistakes",[677,678,679,696,702,712],"ul",{},[680,681,682,688,689,691,692,695],"li",{},[19,683,684,685,687],{},"Using ",[57,686,217],{}," for tokens or passwords."," It is predictable. Always use ",[57,690,519],{}," or ",[57,693,694],{},"randomBytes()",".",[680,697,698,701],{},[19,699,700],{},"Seeding a CSPRNG."," You override the entropy source and defeat its purpose. Let the OS handle it.",[680,703,704,707,708,711],{},[19,705,706],{},"Truncating random values."," Taking ",[57,709,710],{},"Math.random() % 6"," for dice introduces modulo bias — lower numbers appear slightly more often. Use rejection sampling instead.",[680,713,714,717],{},[19,715,716],{},"Sharing a PRNG instance across threads."," Mersenne Twister is not thread-safe. Concurrent calls corrupt the state.",[10,719,721],{"id":720},"key-takeaways","Key Takeaways",[677,723,724,727,730,742,745],{},[680,725,726],{},"PRNGs are deterministic sequences; CSPRNGs pull from OS entropy and are unpredictable.",[680,728,729],{},"Mersenne Twister and xoshiro dominate PRNG usage; choose xoshiro for speed and smaller state.",[680,731,732,733,736,737,736,739,741],{},"Use CSPRNGs (",[57,734,735],{},"crypto",", ",[57,738,306],{},[57,740,360],{},") for anything security-related — passwords, tokens, keys.",[680,743,744],{},"Seeding gives reproducibility in tests but is a vulnerability in production.",[680,746,747],{},"Modulo truncation creates bias — use proper range reduction techniques.",[10,749,751],{"id":750},"try-it-yourself","Try It Yourself",[15,753,754,755,760,761,765,766,770],{},"Generate cryptographically random values right in your browser. Use our ",[756,757,759],"a",{"href":758},"\u002Ftools\u002Frandom-number","Random Number Generator"," to produce secure random integers, our ",[756,762,764],{"href":763},"\u002Ftools\u002Fpassword-generator","Password Generator"," to create strong passwords from CSPRNG entropy, or our ",[756,767,769],{"href":768},"\u002Ftools\u002Fuuid-generator","UUID Generator"," to generate RFC-compliant unique identifiers — all free, no signup required.",[772,773,774],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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 .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":59,"searchDepth":131,"depth":131,"links":776},[777,778,783,789,790,791,792,793,794],{"id":12,"depth":131,"text":13},{"id":32,"depth":131,"text":33,"children":779},[780,781,782],{"id":44,"depth":208,"text":45},{"id":79,"depth":208,"text":80},{"id":104,"depth":208,"text":105},{"id":153,"depth":131,"text":154,"children":784},[785,786,787,788],{"id":160,"depth":208,"text":161},{"id":221,"depth":208,"text":222},{"id":277,"depth":208,"text":278},{"id":318,"depth":208,"text":319},{"id":368,"depth":131,"text":369},{"id":485,"depth":131,"text":486},{"id":609,"depth":131,"text":610},{"id":674,"depth":131,"text":675},{"id":720,"depth":131,"text":721},{"id":750,"depth":131,"text":751},"2026-05-28","Compare pseudo-random and cryptographic randomness across programming languages and learn when each matters.","md",{"immutable":336},"\u002Fguides\u002Frandomness-in-programming",{"title":5,"description":796},"guides\u002Frandomness-in-programming","moo--VBkupWOOy8l9JMKjRISjRKL7BjG3tlsROkn8v8",1780401329041]