[{"data":1,"prerenderedAt":718},["ShallowReactive",2],{"navigation_docs":3,"-guide":148,"-guide-surround":715},[4,40],{"title":5,"path":6,"stem":7,"children":8,"icon":39},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31,35],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Hashing","\u002Fguide\u002Fhashing","1.guide\u002F02.hashing",{"title":16,"path":17,"stem":18},"HMAC and verify","\u002Fguide\u002Fverify","1.guide\u002F03.verify",{"title":20,"path":21,"stem":22},"Salted KDFs","\u002Fguide\u002Fkdf","1.guide\u002F04.kdf",{"title":24,"path":25,"stem":26},"CLI","\u002Fguide\u002Fcli","1.guide\u002F05.cli",{"title":28,"path":29,"stem":30},"Agents","\u002Fguide\u002Fagents","1.guide\u002F06.agents",{"title":32,"path":33,"stem":34},"Custom algorithms","\u002Fguide\u002Fcustom","1.guide\u002F07.custom",{"title":36,"path":37,"stem":38},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F08.playground","i-lucide-book-open",{"title":41,"path":42,"stem":43,"children":44,"icon":147},"Algorithms","\u002Falgorithms","2.algorithms\u002F00.index",[45,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143],{"title":46,"path":42,"stem":43},"Every algorithm",{"title":48,"path":49,"stem":50},"SHA-256","\u002Falgorithms\u002Fsha256","2.algorithms\u002F01.sha256",{"title":52,"path":53,"stem":54},"SHA-384","\u002Falgorithms\u002Fsha384","2.algorithms\u002F02.sha384",{"title":56,"path":57,"stem":58},"SHA-512","\u002Falgorithms\u002Fsha512","2.algorithms\u002F03.sha512",{"title":60,"path":61,"stem":62},"SHA-512Half","\u002Falgorithms\u002Fsha512-half","2.algorithms\u002F04.sha512-half",{"title":64,"path":65,"stem":66},"SHA3-256","\u002Falgorithms\u002Fsha3-256","2.algorithms\u002F05.sha3-256",{"title":68,"path":69,"stem":70},"SHA3-512","\u002Falgorithms\u002Fsha3-512","2.algorithms\u002F06.sha3-512",{"title":72,"path":73,"stem":74},"Keccak-256","\u002Falgorithms\u002Fkeccak256","2.algorithms\u002F07.keccak256",{"title":76,"path":77,"stem":78},"BLAKE2b","\u002Falgorithms\u002Fblake2b","2.algorithms\u002F08.blake2b",{"title":80,"path":81,"stem":82},"BLAKE2b-256","\u002Falgorithms\u002Fblake2b-256","2.algorithms\u002F09.blake2b-256",{"title":84,"path":85,"stem":86},"BLAKE2b-224","\u002Falgorithms\u002Fblake2b-224","2.algorithms\u002F10.blake2b-224",{"title":88,"path":89,"stem":90},"BLAKE2s","\u002Falgorithms\u002Fblake2s","2.algorithms\u002F11.blake2s",{"title":92,"path":93,"stem":94},"BLAKE3","\u002Falgorithms\u002Fblake3","2.algorithms\u002F12.blake3",{"title":96,"path":97,"stem":98},"BLAKE-256","\u002Falgorithms\u002Fblake256","2.algorithms\u002F13.blake256",{"title":100,"path":101,"stem":102},"RIPEMD-160","\u002Falgorithms\u002Fripemd160","2.algorithms\u002F14.ripemd160",{"title":104,"path":105,"stem":106},"HASH160","\u002Falgorithms\u002Fhash160","2.algorithms\u002F15.hash160",{"title":108,"path":109,"stem":110},"HASH256","\u002Falgorithms\u002Fhash256","2.algorithms\u002F16.hash256",{"title":112,"path":113,"stem":114},"MD5","\u002Falgorithms\u002Fmd5","2.algorithms\u002F17.md5",{"title":116,"path":117,"stem":118},"SHA-1","\u002Falgorithms\u002Fsha1","2.algorithms\u002F18.sha1",{"title":120,"path":121,"stem":122},"SHA-0","\u002Falgorithms\u002Fsha0","2.algorithms\u002F19.sha0",{"title":124,"path":125,"stem":126},"CRC-32","\u002Falgorithms\u002Fcrc32","2.algorithms\u002F20.crc32",{"title":128,"path":129,"stem":130},"CRC-16\u002FXMODEM","\u002Falgorithms\u002Fcrc16-xmodem","2.algorithms\u002F21.crc16-xmodem",{"title":132,"path":133,"stem":134},"xxHash (XXH64)","\u002Falgorithms\u002Fxxhash","2.algorithms\u002F22.xxhash",{"title":136,"path":137,"stem":138},"FNV-1a (64-bit)","\u002Falgorithms\u002Ffnv1a","2.algorithms\u002F23.fnv1a",{"title":140,"path":141,"stem":142},"scrypt","\u002Falgorithms\u002Fscrypt","2.algorithms\u002F24.scrypt",{"title":144,"path":145,"stem":146},"PBKDF2","\u002Falgorithms\u002Fpbkdf2","2.algorithms\u002F25.pbkdf2","i-lucide-library",{"id":149,"title":10,"body":150,"description":709,"extension":710,"links":711,"meta":712,"navigation":258,"path":6,"seo":713,"stem":7,"__hash__":714},"docs\u002F1.guide\u002F01.index.md",{"type":151,"value":152,"toc":700},"minimark",[153,158,163,172,175,186,190,215,222,226,314,328,332,339,487,493,497,500,511,515,621,643,647,696],[154,155,157],"warning",{"title":156},"Pre-1.0","The API and the tool list can still move. Pin exact versions if you build on it now.",[159,160,162],"h2",{"id":161},"why-this-exists","Why this exists",[164,165,166,167,171],"p",{},"Ask a model for the SHA-256 of a string. It gives you 64 hex characters, very confidently, and they're wrong. Hashing is the one thing a language model can't fake, so it should call something that actually hashes. ",[168,169,170],"code",{},"@agntn\u002Fhashes"," is that something, and it's the same thing in your TypeScript and in your terminal.",[164,173,174],{},"It also has the hashes chains quietly depend on. Keccak-256 with its pre-SHA-3 padding, HASH160, double SHA-256, BLAKE2b cut to 32 or 28 bytes, SHA-512Half. Those are the ones people get subtly wrong, and subtly wrong means a different address.",[164,176,177,178,181,182,185],{},"No HTTP, no keys, no telemetry, no hashing dependency. Every digest is plain TypeScript in ",[168,179,180],{},"src\u002Fcore\u002F",", and the library imports nothing from ",[168,183,184],{},"node:*",". That's why this site can run it in your browser.",[159,187,189],{"id":188},"install","Install",[191,192,197],"pre",{"className":193,"code":194,"language":195,"meta":196,"style":196},"language-bash shiki shiki-themes hashes hashes hashes","pnpm add @agntn\u002Fhashes\n","bash","",[168,198,199],{"__ignoreMap":196},[200,201,204,208,212],"span",{"class":202,"line":203},"line",1,[200,205,207],{"class":206},"sK71F","pnpm",[200,209,211],{"class":210},"shU9J"," add",[200,213,214],{"class":210}," @agntn\u002Fhashes\n",[164,216,217,218,221],{},"Node.js 26 or newer. It needs ",[168,219,220],{},"Uint8Array"," with native hex and base64, and 26 is where that stopped being a question.",[159,223,225],{"id":224},"first-call","First call",[191,227,232],{"className":228,"code":229,"filename":230,"language":231,"meta":196,"style":196},"language-ts shiki shiki-themes hashes hashes hashes","import { create } from \"@agntn\u002Fhashes\";\n\nconst result = create(\"sha256\").hash(\"abc\");\nresult.digest; \u002F\u002F \"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\"\nresult.digestLength; \u002F\u002F 32\n","first.ts","ts",[168,233,234,253,260,295,305],{"__ignoreMap":196},[200,235,236,240,244,247,250],{"class":202,"line":203},[200,237,239],{"class":238},"skH_V","import",[200,241,243],{"class":242},"s38Sx"," { create } ",[200,245,246],{"class":238},"from",[200,248,249],{"class":210}," \"@agntn\u002Fhashes\"",[200,251,252],{"class":242},";\n",[200,254,256],{"class":202,"line":255},2,[200,257,259],{"emptyLinePlaceholder":258},true,"\n",[200,261,263,266,269,272,275,278,281,284,287,289,292],{"class":202,"line":262},3,[200,264,265],{"class":238},"const",[200,267,268],{"class":242}," result ",[200,270,271],{"class":238},"=",[200,273,274],{"class":206}," create",[200,276,277],{"class":242},"(",[200,279,280],{"class":210},"\"sha256\"",[200,282,283],{"class":242},").",[200,285,286],{"class":206},"hash",[200,288,277],{"class":242},[200,290,291],{"class":210},"\"abc\"",[200,293,294],{"class":242},");\n",[200,296,298,301],{"class":202,"line":297},4,[200,299,300],{"class":242},"result.digest; ",[200,302,304],{"class":303},"scIB-","\u002F\u002F \"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\"\n",[200,306,308,311],{"class":202,"line":307},5,[200,309,310],{"class":242},"result.digestLength; ",[200,312,313],{"class":303},"\u002F\u002F 32\n",[164,315,316,319,320,323,324,327],{},[168,317,318],{},"create(name)"," wants the exact registry key and hands back one cached instance. ",[168,321,322],{},"resolveAlgorithm(\"SHA3_256\")"," forgives case, spaces and underscores, then wants an exact match too. No prefixes, no fuzzy guess. A typo is an ",[168,325,326],{},"UnknownAlgorithmError",", and its message lists every name that does exist.",[159,329,331],{"id":330},"the-shape","The shape",[164,333,334,335,338],{},"Every ",[168,336,337],{},"hash()"," returns this, whatever the algorithm:",[191,340,342],{"className":228,"code":341,"language":231,"meta":196,"style":196},"interface HashResult {\n  digest: string | Uint8Array; \u002F\u002F bytes only with encoding \"binary\"\n  algorithm: string; \u002F\u002F \"sha256\"\n  operation: \"hash\" | \"hmac\";\n  encoding: \"hex\" | \"base64\" | \"base64url\" | \"binary\";\n  digestLength: number; \u002F\u002F bytes of the raw digest\n  options: Record\u003Cstring, unknown>; \u002F\u002F what the digest depends on: encoding, salt, cost, seed\n}\n",[168,343,344,355,378,392,409,436,452,481],{"__ignoreMap":196},[200,345,346,349,352],{"class":202,"line":203},[200,347,348],{"class":238},"interface",[200,350,351],{"class":206}," HashResult",[200,353,354],{"class":242}," {\n",[200,356,357,360,363,366,369,372,375],{"class":202,"line":255},[200,358,359],{"class":242},"  digest",[200,361,362],{"class":238},":",[200,364,365],{"class":206}," string",[200,367,368],{"class":238}," |",[200,370,371],{"class":206}," Uint8Array",[200,373,374],{"class":242},"; ",[200,376,377],{"class":303},"\u002F\u002F bytes only with encoding \"binary\"\n",[200,379,380,383,385,387,389],{"class":202,"line":262},[200,381,382],{"class":242},"  algorithm",[200,384,362],{"class":238},[200,386,365],{"class":206},[200,388,374],{"class":242},[200,390,391],{"class":303},"\u002F\u002F \"sha256\"\n",[200,393,394,397,399,402,404,407],{"class":202,"line":297},[200,395,396],{"class":242},"  operation",[200,398,362],{"class":238},[200,400,401],{"class":210}," \"hash\"",[200,403,368],{"class":238},[200,405,406],{"class":210}," \"hmac\"",[200,408,252],{"class":242},[200,410,411,414,416,419,421,424,426,429,431,434],{"class":202,"line":307},[200,412,413],{"class":242},"  encoding",[200,415,362],{"class":238},[200,417,418],{"class":210}," \"hex\"",[200,420,368],{"class":238},[200,422,423],{"class":210}," \"base64\"",[200,425,368],{"class":238},[200,427,428],{"class":210}," \"base64url\"",[200,430,368],{"class":238},[200,432,433],{"class":210}," \"binary\"",[200,435,252],{"class":242},[200,437,439,442,444,447,449],{"class":202,"line":438},6,[200,440,441],{"class":242},"  digestLength",[200,443,362],{"class":238},[200,445,446],{"class":206}," number",[200,448,374],{"class":242},[200,450,451],{"class":303},"\u002F\u002F bytes of the raw digest\n",[200,453,455,458,460,463,466,469,472,475,478],{"class":202,"line":454},7,[200,456,457],{"class":242},"  options",[200,459,362],{"class":238},[200,461,462],{"class":206}," Record",[200,464,465],{"class":242},"\u003C",[200,467,468],{"class":206},"string",[200,470,471],{"class":242},", ",[200,473,474],{"class":206},"unknown",[200,476,477],{"class":242},">; ",[200,479,480],{"class":303},"\u002F\u002F what the digest depends on: encoding, salt, cost, seed\n",[200,482,484],{"class":202,"line":483},8,[200,485,486],{"class":242},"}\n",[164,488,489,492],{},[168,490,491],{},"options"," is the part people skip and then regret. For scrypt it holds the salt it drew and the cost it ran with, and without those the digest is a string that looks random and that you can never reproduce.",[159,494,496],{"id":495},"what-ships","What ships",[498,499],"algorithm-roster",{},[164,501,502,503,506,507,510],{},"Every row comes from ",[168,504,505],{},"create(name).info()",", read in your browser. The HMAC column says which ones take a ",[168,508,509],{},"key",". The rest refuse it with an error, they don't quietly hash without it.",[159,512,514],{"id":513},"errors","Errors",[191,516,518],{"className":228,"code":517,"language":231,"meta":196,"style":196},"import { HashError, InvalidOptionError, UnknownAlgorithmError, create } from \"@agntn\u002Fhashes\";\n\ntry {\n  create(\"scrypt\").hash(\"password\", { N: 1000 });\n} catch (error) {\n  if (error instanceof InvalidOptionError) {\n    error.option; \u002F\u002F \"N\"\n    error.reason; \u002F\u002F \"must be a power of 2 and >= 2\"\n  }\n}\n",[168,519,520,533,537,544,566,577,594,602,610,616],{"__ignoreMap":196},[200,521,522,524,527,529,531],{"class":202,"line":203},[200,523,239],{"class":238},[200,525,526],{"class":242}," { HashError, InvalidOptionError, UnknownAlgorithmError, create } ",[200,528,246],{"class":238},[200,530,249],{"class":210},[200,532,252],{"class":242},[200,534,535],{"class":202,"line":255},[200,536,259],{"emptyLinePlaceholder":258},[200,538,539,542],{"class":202,"line":262},[200,540,541],{"class":238},"try",[200,543,354],{"class":242},[200,545,546,549,551,554,556,558,560,563],{"class":202,"line":297},[200,547,548],{"class":206},"  create",[200,550,277],{"class":242},[200,552,553],{"class":210},"\"scrypt\"",[200,555,283],{"class":242},[200,557,286],{"class":206},[200,559,277],{"class":242},[200,561,562],{"class":210},"\"password\"",[200,564,565],{"class":242},", { N: 1000 });\n",[200,567,568,571,574],{"class":202,"line":307},[200,569,570],{"class":242},"} ",[200,572,573],{"class":238},"catch",[200,575,576],{"class":242}," (error) {\n",[200,578,579,582,585,588,591],{"class":202,"line":438},[200,580,581],{"class":238},"  if",[200,583,584],{"class":242}," (error ",[200,586,587],{"class":238},"instanceof",[200,589,590],{"class":206}," InvalidOptionError",[200,592,593],{"class":242},") {\n",[200,595,596,599],{"class":202,"line":454},[200,597,598],{"class":242},"    error.option; ",[200,600,601],{"class":303},"\u002F\u002F \"N\"\n",[200,603,604,607],{"class":202,"line":483},[200,605,606],{"class":242},"    error.reason; ",[200,608,609],{"class":303},"\u002F\u002F \"must be a power of 2 and >= 2\"\n",[200,611,613],{"class":202,"line":612},9,[200,614,615],{"class":242},"  }\n",[200,617,619],{"class":202,"line":618},10,[200,620,486],{"class":242},[164,622,623,624,626,627,630,631,634,635,638,639,642],{},"A name nobody registered is an ",[168,625,326],{},". A bad value is an ",[168,628,629],{},"InvalidOptionError"," with the option, the value and the reason. A required one left out is a ",[168,632,633],{},"MissingOptionError",". Anything else an algorithm throws gets wrapped by ",[168,636,637],{},"normalizeError"," into a ",[168,640,641],{},"HashError"," that names the algorithm. The CLI prints the message on one line and exits 1. No stack trace, the input was wrong, not you.",[159,644,646],{"id":645},"next","Next",[648,649,650,657,662,667,676,681,690],"ul",{},[651,652,653,656],"li",{},[654,655,12],"a",{"href":13},": encodings, text versus bytes, names.",[651,658,659,661],{},[654,660,16],{"href":17},": keys, and comparing digests without a timing leak.",[651,663,664,666],{},[654,665,20],{"href":21},": scrypt and PBKDF2, and why they print the salt.",[651,668,669,671,672,675],{},[654,670,24],{"href":25},": the ",[168,673,674],{},"hashes"," command.",[651,677,678,680],{},[654,679,28],{"href":29},": the same tools over MCP, Pi, OMP and the AI SDK.",[651,682,683,685,686,689],{},[654,684,32],{"href":33},": extend ",[168,687,688],{},"FixedHash",", register it.",[651,691,692,695],{},[654,693,36],{"href":694},"\u002Fplayground",": every algorithm, in the page.",[697,698,699],"style",{},"html pre.shiki code .sK71F, html code.shiki .sK71F{--shiki-light:var(--shiki-token-function);--shiki-default:var(--shiki-token-function);--shiki-dark:var(--shiki-token-function)}html pre.shiki code .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .skH_V, html code.shiki .skH_V{--shiki-light:var(--shiki-token-keyword);--shiki-default:var(--shiki-token-keyword);--shiki-dark:var(--shiki-token-keyword)}html pre.shiki code .s38Sx, html code.shiki .s38Sx{--shiki-light:var(--ui-text-highlighted);--shiki-default:var(--ui-text-highlighted);--shiki-dark:var(--ui-text-highlighted)}html pre.shiki code .scIB-, html code.shiki .scIB-{--shiki-light:var(--shiki-token-comment);--shiki-default:var(--shiki-token-comment);--shiki-dark:var(--shiki-token-comment)}",{"title":196,"searchDepth":255,"depth":255,"links":701},[702,703,704,705,706,707,708],{"id":161,"depth":255,"text":162},{"id":188,"depth":255,"text":189},{"id":224,"depth":255,"text":225},{"id":330,"depth":255,"text":331},{"id":495,"depth":255,"text":496},{"id":513,"depth":255,"text":514},{"id":645,"depth":255,"text":646},"Install the package and hash one string. Every algorithm answers with the same result shape","md",null,{"icon":39},{"title":10,"description":709},"Xyl4FVTaOl0l0DoQWlcxoAEyXekItzLj55nCbwidgG8",[711,716],{"title":12,"path":13,"stem":14,"description":717,"children":-1},"Pick an algorithm by name and hash text or bytes. Hex and base64 and base64url or raw bytes out",1790683655811]