[{"data":1,"prerenderedAt":446},["ShallowReactive",2],{"navigation_docs":3,"-guide-identify":84,"-guide-identify-surround":441},[4,48],{"title":5,"path":6,"stem":7,"children":8,"icon":47},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31,35,39,43],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Compressing","\u002Fguide\u002Fcompressing","1.guide\u002F02.compressing",{"title":16,"path":17,"stem":18},"Containers","\u002Fguide\u002Fcontainers","1.guide\u002F03.containers",{"title":20,"path":21,"stem":22},"Checksums","\u002Fguide\u002Fchecksums","1.guide\u002F04.checksums",{"title":24,"path":25,"stem":26},"Identify and peel","\u002Fguide\u002Fidentify","1.guide\u002F05.identify",{"title":28,"path":29,"stem":30},"Limits","\u002Fguide\u002Flimits","1.guide\u002F06.limits",{"title":32,"path":33,"stem":34},"CLI","\u002Fguide\u002Fcli","1.guide\u002F07.cli",{"title":36,"path":37,"stem":38},"Agents","\u002Fguide\u002Fagents","1.guide\u002F08.agents",{"title":40,"path":41,"stem":42},"Custom formats","\u002Fguide\u002Fcustom","1.guide\u002F09.custom",{"title":44,"path":45,"stem":46},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F10.playground","i-lucide-book-open",{"title":49,"path":50,"stem":51,"children":52,"icon":83},"Formats","\u002Fformats","2.formats\u002F00.index",[53,55,59,63,67,71,75,79],{"title":54,"path":50,"stem":51},"Every format",{"title":56,"path":57,"stem":58},"deflate","\u002Fformats\u002Fdeflate","2.formats\u002F01.deflate",{"title":60,"path":61,"stem":62},"bzip2","\u002Fformats\u002Fbzip2","2.formats\u002F02.bzip2",{"title":64,"path":65,"stem":66},"LZMA","\u002Fformats\u002Flzma","2.formats\u002F03.lzma",{"title":68,"path":69,"stem":70},"Zstandard","\u002Fformats\u002Fzstd","2.formats\u002F04.zstd",{"title":72,"path":73,"stem":74},"Brotli","\u002Fformats\u002Fbrotli","2.formats\u002F05.brotli",{"title":76,"path":77,"stem":78},"LZ4","\u002Fformats\u002Flz4","2.formats\u002F06.lz4",{"title":80,"path":81,"stem":82},"Unix compress","\u002Fformats\u002Flzw","2.formats\u002F07.lzw","i-lucide-library",{"id":85,"title":24,"body":86,"description":434,"extension":435,"links":436,"meta":437,"navigation":139,"path":25,"seo":439,"stem":26,"__hash__":440},"docs\u002F1.guide\u002F05.identify.md",{"type":87,"value":88,"toc":428},"minimark",[89,94,102,169,180,184,259,262,268,272,281,296,303,307,313,399,413,424],[90,91,93],"h2",{"id":92},"try-it-dont-guess-it","Try it, don't guess it",[95,96,97,101],"p",{},[98,99,100],"code",{},"identify"," doesn't pattern match and hope. It tries every container whose start fits, decompresses for real, and ranks what worked:",[103,104,109],"pre",{"className":105,"code":106,"language":107,"meta":108,"style":108},"language-ts shiki shiki-themes compressions compressions compressions","import { identify } from \"@agntn\u002Fcompressions\";\n\nidentify(gz);\n\u002F\u002F [{ format: \"deflate\", container: \"gzip\", confidence: 100, confirmed: true,\n\u002F\u002F    reasons: [\"starts with its magic number\", \"checksum matches\",\n\u002F\u002F              \"decodes to the last byte\", \"decompresses to readable text\"], bytes, details }]\n","ts","",[98,110,111,134,141,150,157,163],{"__ignoreMap":108},[112,113,116,120,124,127,131],"span",{"class":114,"line":115},"line",1,[112,117,119],{"class":118},"skH_V","import",[112,121,123],{"class":122},"s38Sx"," { identify } ",[112,125,126],{"class":118},"from",[112,128,130],{"class":129},"shU9J"," \"@agntn\u002Fcompressions\"",[112,132,133],{"class":122},";\n",[112,135,137],{"class":114,"line":136},2,[112,138,140],{"emptyLinePlaceholder":139},true,"\n",[112,142,144,147],{"class":114,"line":143},3,[112,145,100],{"class":146},"sK71F",[112,148,149],{"class":122},"(gz);\n",[112,151,153],{"class":114,"line":152},4,[112,154,156],{"class":155},"scIB-","\u002F\u002F [{ format: \"deflate\", container: \"gzip\", confidence: 100, confirmed: true,\n",[112,158,160],{"class":114,"line":159},5,[112,161,162],{"class":155},"\u002F\u002F    reasons: [\"starts with its magic number\", \"checksum matches\",\n",[112,164,166],{"class":114,"line":165},6,[112,167,168],{"class":155},"\u002F\u002F              \"decodes to the last byte\", \"decompresses to readable text\"], bytes, details }]\n",[95,170,171,172,175,176,179],{},"Each candidate carries the decompressed ",[98,173,174],{},"bytes",", the ",[98,177,178],{},"details"," and the reasons behind its score. The confidence ranks, it isn't a probability.",[90,181,183],{"id":182},"what-counts","What counts",[185,186,187,200],"table",{},[188,189,190],"thead",{},[191,192,193,197],"tr",{},[194,195,196],"th",{},"Evidence",[194,198,199],{},"Points",[201,202,203,212,220,228,236,244,251],"tbody",{},[191,204,205,209],{},[206,207,208],"td",{},"starts with its magic number",[206,210,211],{},"50",[191,213,214,217],{},[206,215,216],{},"header fields are valid (zlib, .lzma)",[206,218,219],{},"25",[191,221,222,225],{},[206,223,224],{},"checksum matches",[206,226,227],{},"30",[191,229,230,233],{},[206,231,232],{},"decodes to the last byte",[206,234,235],{},"10",[191,237,238,241],{},[206,239,240],{},"bytes follow the stream",[206,242,243],{},"minus 15",[191,245,246,249],{},[206,247,248],{},"decompresses to readable text",[206,250,235],{},[191,252,253,256],{},[206,254,255],{},"comes out longer than it went in",[206,257,258],{},"5",[95,260,261],{},"A container with a magic number is tried only when the bytes start with it. zlib and .lzma have no real magic, so their headers get checked instead: zlib's two bytes carry their own check, .lzma's properties and sizes have to make sense. Raw deflate and brotli have neither. They get tried on everything, and they only count when they decode every single byte and give something back, since random bytes decode as deflate more often than you'd think.",[95,263,264,267],{},[98,265,266],{},"confirmed"," marks a candidate backed by more than luck: a magic number, or a checked header with a checksum or readable text behind it.",[90,269,271],{"id":270},"when-nothing-fits","When nothing fits",[95,273,274,276,277,280],{},[98,275,100],{}," returns an empty list. That's an answer, not a failure. Plain text isn't compressed. And when the bytes start like an archive this package doesn't open, ",[98,278,279],{},"archiveOf"," names it:",[103,282,284],{"className":105,"code":283,"language":107,"meta":108,"style":108},"archiveOf(zipBytes);  \u002F\u002F \"a ZIP archive\"\n",[98,285,286],{"__ignoreMap":108},[112,287,288,290,293],{"class":114,"line":115},[112,289,279],{"class":146},[112,291,292],{"class":122},"(zipBytes);  ",[112,294,295],{"class":155},"\u002F\u002F \"a ZIP archive\"\n",[95,297,298,299,302],{},"ZIP, 7-Zip, RAR, tar, cabinet files, lzip and PNG are on that list. A ZIP entry's data is usually raw deflate, so once you've cut it out, ",[98,300,301],{},"decompress(\"deflate\", entry)"," reads it.",[90,304,306],{"id":305},"peel","Peel",[95,308,309,310,312],{},"Puzzles love nesting. ",[98,311,305],{}," takes off one layer after another while each is confirmed:",[103,314,316],{"className":105,"code":315,"language":107,"meta":108,"style":108},"import { peel } from \"@agntn\u002Fcompressions\";\n\npeel(compress(\"bzip2\", compress(\"lzma\", compress(\"deflate\", text, { container: \"gzip\" }), { container: \"xz\" })));\n\u002F\u002F bzip2 · bzip2, 90, confirmed\n\u002F\u002F lzma  · xz,    90, confirmed\n\u002F\u002F deflate · gzip, 100, confirmed\n",[98,317,318,331,335,384,389,394],{"__ignoreMap":108},[112,319,320,322,325,327,329],{"class":114,"line":115},[112,321,119],{"class":118},[112,323,324],{"class":122}," { peel } ",[112,326,126],{"class":118},[112,328,130],{"class":129},[112,330,133],{"class":122},[112,332,333],{"class":114,"line":136},[112,334,140],{"emptyLinePlaceholder":139},[112,336,337,339,342,345,347,350,353,355,357,360,362,364,366,369,372,375,378,381],{"class":114,"line":143},[112,338,305],{"class":146},[112,340,341],{"class":122},"(",[112,343,344],{"class":146},"compress",[112,346,341],{"class":122},[112,348,349],{"class":129},"\"bzip2\"",[112,351,352],{"class":122},", ",[112,354,344],{"class":146},[112,356,341],{"class":122},[112,358,359],{"class":129},"\"lzma\"",[112,361,352],{"class":122},[112,363,344],{"class":146},[112,365,341],{"class":122},[112,367,368],{"class":129},"\"deflate\"",[112,370,371],{"class":122},", text, { container: ",[112,373,374],{"class":129},"\"gzip\"",[112,376,377],{"class":122}," }), { container: ",[112,379,380],{"class":129},"\"xz\"",[112,382,383],{"class":122}," })));\n",[112,385,386],{"class":114,"line":152},[112,387,388],{"class":155},"\u002F\u002F bzip2 · bzip2, 90, confirmed\n",[112,390,391],{"class":114,"line":159},[112,392,393],{"class":155},"\u002F\u002F lzma  · xz,    90, confirmed\n",[112,395,396],{"class":114,"line":165},[112,397,398],{"class":155},"\u002F\u002F deflate · gzip, 100, confirmed\n",[95,400,401,402,404,405,408,409,412],{},"The list runs outermost first, and the last layer's ",[98,403,174],{}," is what's at the bottom. An unconfirmed best guess ends the list, marked ",[98,406,407],{},"confirmed: false",", so you see it without the next layer building on it. ",[98,410,411],{},"depth"," caps the layers, 10 by default.",[95,414,415,416,419,420,423],{},"The tool does the same with ",[98,417,418],{},"peel: true",", and hands the innermost bytes back in base64. On the CLI, ",[98,421,422],{},"compressions identify --peel file"," lists the layers on stderr and writes the bottom to stdout.",[425,426,427],"style",{},"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 .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}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 .scIB-, html code.shiki .scIB-{--shiki-light:var(--shiki-token-comment);--shiki-default:var(--shiki-token-comment);--shiki-dark:var(--shiki-token-comment)}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);}",{"title":108,"searchDepth":136,"depth":136,"links":429},[430,431,432,433],{"id":92,"depth":136,"text":93},{"id":182,"depth":136,"text":183},{"id":270,"depth":136,"text":271},{"id":305,"depth":136,"text":306},"Which format made these bytes. Ranked by magic numbers and headers and checksums and every layer peeled off in one call","md",null,{"icon":438},"i-lucide-scan-search",{"title":24,"description":434},"yZFhWSiPLy5E5t-Evl3zDtVtVw7-ZYAGaYTux0mdLvo",[442,444],{"title":20,"path":21,"stem":22,"description":443,"children":-1},"CRC-32 and Adler-32 and CRC-64 and XXH32 and XXH64. Every one checked on the way out and a wrong one is an error",{"title":28,"path":29,"stem":30,"description":445,"children":-1},"An output limit so a bomb stays small and partial reads for streams that break halfway",1791071141269]