Base62-kodning / -avkodning

Konvertera ett tal eller en bytesträng med Base62: 62 tecken bestående av siffror, versala bokstäver och gemena bokstäver, som ingen behöver escapas i en URL-frågesträng eller i HTML-text. Det är därför korta länkar och automatiskt ökande ID:n skrivs så. Två lägen: ett decimalt tal (ett ID blir en kort kod) och byte (text eller hexadecimal indata). Också: Base64 | Base32 / Base58 | Base91.
All bearbetning sker lokalt i webbläsaren — data laddas aldrig upp till någon server.

Aldrig hört talas om Base62? Vad är Base62 — förklarat på enkel svenska (med genomarbetade exempel, de tre alfabeten och fallgroparna).
Alfabet:
Fyll ut resultatet till en fast bredd: 0 = ingen utfyllnad. Utfyllnad upprepar nolltecknet i det valda alfabetet, så samma tal fylls ut olika i bokstäver-först-alfabetet.
Så fungerar det:
Indata är:
Så fungerar det:
Utdata som:
Ctrl+Enter i indatan kör det aktiva läget.
Välj Koda eller Avkoda och klicka på åtgärdsknappen. Knappen Självtest kör varje dokumenterat exempel, varje längd från 0 till 64 byte och en spridning av decimala tal genom alla tre alfabet, och redovisar antalet här.
De tre alfabeten, utskrivna i sin helhet: Base62 har ingen standardiseringsorganisation bakom sig, så alfabetet är inte garanterat mellan implementationer. Dessa är de tre ordningarna som faktiskt förekommer i verkligheten; varje en skrivs ut tecken för tecken med sitt värde, så att varje resultat kan spåras tillbaka till exakt det alfabet som skapade det. Den skuggade cellen är tecknet som betyder noll, som inte är samma tecken i alla tre.
Base62 är skiftlägeskänsligt i var och en av de tre ordningarna: en versal bokstav och dess gemena form betecknar nästan alltid olika värden, så en kod som har passerat ett steg med gemener är ett annat tal, inte ett fel.
Base62 är skiftlägeskänsligt i var och en av de tre ordningarna: en versal bokstav och dess gemena form betecknar nästan alltid olika värden, så en kod som har passerat ett steg med gemener är ett annat tal, inte ett fel.
Längd på samma byte i varje kodning:
Hur stor indata den här sidan accepterar, och varför: alla lägen här omvandlar via ett enda stort heltal, och omvandling av stora heltal kostar tid proportionellt mot kvadraten på längden. Det är en egenskap hos formatet självt, inte hos den här sidan: varje verktyg som implementerar riktig Base62 har samma form av gräns. Talen nedan kommer från en tidtagningsmiljö som kör sidans egna rutiner snarare än från en körande flik, och de är därför avsiktligt på den pessimistiska sidan: en stationär webbläsare brukar bli klar flera gånger snabbare, och den marginalen täcker en långsam telefon. Gränserna är satta så att även det långsamma fallet blir klart i stället för att frysa fliken.
Ovanför den mjuka gränsen förklarar första klicket kostnaden och begär ett andra klick innan körningen startar; ovanför den hårda gränsen vägrar sidan i stället för att frysa fliken i flera sekunder utan något sätt att visa framsteg. Bytesläget räknas i byte när det kodar och i tecken när det avkodar, och teckenantalet är alltid det större: 2 048 byte skrivs ut som cirka 2 751 tecken, vilket ligger över teckengränsen, så en nyttolast på cirka 1 520 byte eller mindre är vad som överlever en tur och retur på den här sidan. För vanliga binärdata av verklig storlek är Base64 och Base91 linjära och saknar en sådan gräns.
Vad är Base62?

Base62 är ett sätt att skriva ett tal med enbart de tecken som överlever att klistras in var som helst: de tio siffrorna, de 26 versala bokstäverna och de 26 gemena bokstäverna. Ingen interpunktion, inga blanksteg, ingen utfyllnadstecken, ingenting som måste escapas innan det kommer in i en URL, ett filnamn, en cookie eller en databasnyckel. Tio plus 26 plus 26 är 62, och det är därifrån namnet kommer.

Versionen på 30 sekunder: talet 12345 skrivs som 3D7, och 1234567890 skrivs som 1LY7VK. Att gå tillbaka är samma operation baklänges, och det kräver exakt det alfabet som skapade koden — ett annat alfabet gör om samma sex tecken till ett annat tal, utan något felmeddelande.

Den här sidan gör två närbesläktade saker, och skillnaden mellan dem spelar större roll än något annat på sidan:

  • Heltalsläge behandlar indata som ett tal. Ett decimalt ID som 1234567890 blir 1LY7VK, och indatans inledande nollor är inte en del av värdet, så de kommer inte tillbaka.
  • Bytesläge behandlar indata som en bytesträng. Byten läses som ett enda stort heltal i big-endian och delas sedan med 62, vilket är samma aritmetik på en annan storhet. Här överlever antalet inledande nollbyte, ett nollbyte per nolltecken.
Var 62 kommer ifrån och vad det kostar

62 är inte en potens av två, och just det faktumet formar allt annat. De bekanta kodningarna byggs genom att skära indata i fasta bitgrupper: 4 bitar skrivs som ett hexadecimalt tecken, 6 bitar som ett Base64-tecken, 5 bitar som ett Base32-tecken. Base62 kan inte göra så, eftersom inget helt antal bitar passar ett tecken med 62 värden — 5 bitar anger bara 32 värden, 6 bitar anger 64. Därför går Base62 via aritmetik i stället: läs hela indata som ett heltal och skriv ut det i bas 62.

Ett tecken bär då log2(62) = 5,954 bitar, vilket ligger mycket nära Base64:s 6, och i decimalläge ersätter ett tecken log62(10) = 1,792 decimala siffror. Några konsekvenser som är värda att känna till innan man väljer en längd:

KodlängdVärden den kan angeI praktiken
4 tecken624 = 14 776 336Tillräckligt för en räknare som stannar under åtta siffror, och det ryms i utrymmet för ett telefonnummer.
6 tecken626 = 56 800 235 584Den vanliga formen för en ID-kod. Ett decimalt ID med tio siffror ryms i sex tecken.
7 tecken627 = 3 521 614 606 208Över räckvidden för en 32-bitars räknare med två storleksordningar, i bredden av en kort länkslug.
11 tecken6211 = 52 036 560 683 837 093 888Mer än 264 = 18 446 744 073 709 551 616, så ett fullständigt 64-bitars tal ryms i elva tecken.

Åt andra hållet: 1 000 decimala siffror behöver cirka 558 tecken, och 4 096 decimala siffror behöver 2 285. Besparingen är verklig men begränsad: Base62 förkortar ett decimalt tal med ungefär 44 %, och den slår aldrig de tätaste utskrivbara kodningarna, eftersom 5,954 bitar per tecken helt enkelt är mindre än 6,4 eller 6,5.

Heltalsläge: vad som händer med inledande nollor

Ett heltal har en kanonisk skriven form och den börjar med alfabetets nolltecken, som är 0 i de två siffror-först-ordningarna och A i bokstäver-först-ordningen. Allt till vänster om det första betydelsebärande tecknet är utfyllnad, och utfyllnad är inte en del av ett värde: 00012345 och 12345 blir båda 3D7. Om en fast bredd önskas — till exempel en sjusiffrig kod som måste ligga i linje i en kolumn — upprepar rutan Fyll ut resultatet till en fast bredd nolltecken tills bredden är nådd, så 12345 med bredd 7 skrivs ut som 00003D7 i siffror-först-alfabetet och AAAADNH i bokstäver-först-alfabetet. Utfyllnaden är kosmetisk: de inledande tecknen tillför ingenting till värdet, och avkodning av någon av strängarna ger tillbaka 12345, eftersom 0 × 626 och 0 × 625 båda är noll oavsett vilket tecken som stavar nollan.

Avkodning av en utfylld sträng fungerar alltså också, och sidan anger hur många av de inledande tecknen som var nolltecken, så att skillnaden mellan "koden är sju tecken" och "värdet behövde tre tecken" aldrig är en gåta.

Bytesläge: samma aritmetik på en bytesträng

Bytesläget läser indatabyten som ett enda heltal i big-endian — hela bytesträngen behandlas som ett enda tal, hur lång den än är — och skriver ut talet i bas 62. Eftersom en byte innehåller 8 bitar och ett tecken motsvarar 5,954 av dem är bytesläget inte komprimering: det behöver cirka 134 % av indatans storlek, marginellt sämre än Base64:s 133 %. På exemplet med 92 byte i storlekstabellen ovan skrivs 92 byte ut som 124 Base62-tecken, och Base64 skriver också ut 124 (123 av dem före dess =-utfyllnad). Base62 förlorar mot Base64 på täthet och vinner på teckensäkerhet, vilket är den avvägning som varje kort länk och varje inbjudningskod gör med avsikt.

Inledande nollbyte bevaras, och det är lätt att göra fel åt båda hållen. Två inledande nollbyte följda av 0x01 skrivs som 001 i siffror-först-alfabetet och som AAB i bokstäver-först-alfabetet, eftersom de inledande tecknen stavar noll och det blir ett tecken per nollbyte. En bytesträng bestående av ett enda 0x00 skrivs som det enda tecknet 0, och en bytesträng bestående av ett enda 0x01 skrivs som 1. Det här är det enda stället där bytesläget och heltalsläget ser olika ut när de kör samma algoritm.

Priset för det här är att bytesläget ärver aritmetikens kvadratiska tidsåtgång: 1 024 byte beräknas ta cirka en tredjedels sekund och 2 048 byte cirka 1,3 sekunder, samma siffror som gränstabellen ovan anger. Därför är bytesläget här begränsat till 2 048 byte utgående och 2 048 tecken inkommande — 2 048 byte skrivs ut som cirka 2 751 tecken, så cirka 1 520 byte är den största nyttolast som överlever en tur och retur genom den här sidan — och därför är bytesläget på den här sidan en referens för små värden, inte en ersättning för Base64 eller Base91 på riktiga filer.

De tre alfabeten, och varför alfabetet är hela historien

Tecknen i ett alfabet är en fast följd, och ett tecken värde är dess position i följden. Att flytta om följden ändrar vad varje tecken betyder. Tre ordningar används i stor utsträckning, och detta är samma tal skrivet på tre sätt i var och en av dem:

Decimalt0-9 sedan A-Z sedan a-z0-9 sedan a-z sedan A-ZA-Z sedan a-z sedan 0-9
000A
61zZ9
621010BA
12 3453D73d7DNH
1 234 567 8901LY7VK1ly7vkBViHfU

Läser man de tre sista kolumnerna som ett och samma alfabet är det ett sammanhängande schema. Läser man dem som utbytbara faller det ihop, eftersom avkodningen är alfabetsblind på det värsta möjliga sättet: varje tecken i indata finns i alla tre alfabeten, så ett fel alfabet ger inget fel alls, bara ett annat tal.

En kodLäst som 0-9 A-Z a-zLäst som 0-9 a-z A-ZLäst som A-Z a-z 0-9
3D712 34513 957211 665
1LY7VK1 234 567 8901 624 950 79248 723 527 772

Skiftläget är en andra, skarpare variant av samma fallgrop. Base62 är skiftlägeskänsligt i varje ordning, så att skriva en kod med gemener skriver tyst om den: 1LY7VK är 1 234 567 890 i det siffror-först-alfabetet, medan 1ly7vk är 1 624 950 792 i samma alfabet — och det är råkar vara 1 234 567 890 i siffror-sedan-gemener-alfabetet, eftersom den ordningen är precis den siffror-först-ordningen med de två bokstavsvarianterna bytta. Nolltecknet delas inte heller: de två siffror-först-ordningarna skriver noll som 0, medan bokstäver-först-ordningen skriver den som A, så det alfabetet börjar inte med en siffra alls.

Base62 jämfört med de andra kodningarna
KodningBitar per teckenStorlek jämfört med indataAnteckningar
Base16 (hex)4200%Två tecken per byte, lätt att läsa, inget alfabet att slå upp.
Base325160%Skiftlägesokänslig och säker för diktering, den mest slösaktiga i gruppen.
Base36 (0-9 a-z)~5,17~155%Endast siffror och gemener, så den klarar en kedja som gör om skiftläge. 12345 är 9ix.
Base58~5,86~137%Vald för adresser, inte för täthet: fyra lika utseende tecken utelämnas i stället för att ordnas. Se Base32 / Base58.
Base62~5,95~134%Varje tecken är en siffra eller en bokstav, så inget behöver någonsin escapas. Tätheten ligger mellan Base58 och Base64.
Base646133%Standard överallt, till priset av +, / och =, de tre tecken som tvingar fram escapning. Se Base64-konverterare.
Ascii85 / Base856,4125%5 tecken per 4 byte, men den dividerar med 85 och dess alfabet måste citeras. Se Ascii85.
Base91~6,5~123%Den tätaste av dessa, och den vars utdata är minst säker att klistra in oescapad. Se Base91.

Procenttalen är asymptotiska kostnader, avrundade; de uppmätta teckenantalen för en verklig indata på 92 byte finns i storlekstabellen längre upp på sidan. I heltalsläget går jämförelsen åt andra hållet, eftersom indata är decimal text och inte byte: där är Base62 cirka 44 % kortare än siffrorna det ersätter, och Base36 cirka 36 % kortare, vilket är anledningen till att en ID-kod normalt är Base62 eller Base36 och inte Base58.

Vad Base62 inte är
  • Ingen standard. Det finns ingen RFC och ingen specifikation. Ingen standardiseringsorganisation har någonsin definierat Base62, och därför är alfabetet inte garanterat, och därför skriver den här sidan ut alla tre ordningarna i stället för att tyst välja en.
  • Inte kryptering. Det är en basomvandling, inget mer. Den som känner till alfabetet vänder den i ett pass, och det finns ingen nyckel, inget salt och ingen hemlighet av något slag.
  • Inte komprimering. Bytesläget gör datan ungefär en tredjedel större. Heltalsläget ser bara ut som komprimering eftersom decimal text är ett ineffektivt sätt att skriva ett tal från början.
  • Inte skiftlägesokänsligt. Base32 kan skrivas med gemener och läsas tillbaka; Base62 kan inte det. En kod som passerar ett system som normaliserar skiftläge är en skadad kod.
  • Inte självkontrollerande. Det finns ingen kontrollsumma och inget kontrolltecken, så ett enda felaktigt tecken ger ett giltigt utseende resultat med ett annat värde. Om det spelar roll har Bitcoin-ordningen en kontrollsumma — se avsnittet om Base58Check i Base32 / Base58.
  • Ingen fast längd. Antalet tecken växer med värdet, så en räknare som börjar på 1 och når 627 går från ett tecken till åtta. Fyll ut till en fast bredd när en stabil kolumn behövs.
Fallgropar som faktiskt bits
  • Alfabetet är svaret på nio av tio gåtor. Om ett annat verktyg ger en annan kod för samma tal, jämför de två alfabeten tecken för tecken innan ett fel misstänks. Tabellen ovan visar samma värde i tre alfabet, och alla tre är korrekta.
  • Ett fel alfabet misslyckas tyst. Det finns ingen felväg för det: 3D7 avkodas till 12 345, 13 957 eller 211 665 enbart beroende på vilken ordning som antas. Kontrollera det första tecknet, som mest sannolikt är en nollutfyllnad, och kontrollera om alfabetet har siffror eller bokstäver först.
  • Inledande nollor betyder två olika saker. I heltalsläge är 00012345 och 12345 samma tal och skrivs ut identiskt. I bytesläge är ett inledande nollbyte data, och det skrivs ut som ett extra nolltecken. Att ta bort ett av de tecknen ändrar bytesträngen.
  • Normalisering av skiftläge förstör en kod. En e-postadress, ett värdnamn eller en Windows-sökväg kan skrivas med gemener under transport. En Base62-kod överlever inte det, vilket är skälet till att Base36 fortfarande finns.
  • Långa indata är långsamma, inte bara stora. Omvandlingen är aritmetik på hela indata på en gång, så att fördubbla indatans längd fyrdubblar tiden. Den här sidan vägrar indata utöver sina uppmätta gränser i stället för att hänga sig; storlekstabellen längre upp anger de uppmätta talen.
  • En Base62-sträng är inget bevis på något. Eftersom nästan vilken sträng av siffror och bokstäver som helst avkodas utan klagomål, kommer en godtycklig URL-slug att avkodas till något tal. En kod betyder bara något om systemet som utfärdade den också lagrar avbildningen.
Snabba svar

“Varför ger ett annat Base62-verktyg en annan kod för samma tal?”

Eftersom alfabetet skiljer sig åt. Base62 har ingen specifikation att komma överens om, så implementationer väljer en ordning: siffror och versaler först, siffror och gemener först, eller bokstäver före siffror. Byt alfabetsvalet högst upp på den här sidan för att se alla tre svaren sida vid sida.

“Är Base62 säkert i en URL?”

Ja, i var och en av de tre ordningarna. Alla 62 tecken är oescapade bokstäver och siffror, så inget av dem expanderas till en procenttrippel i en frågesträng, och inget av dem avslutar en URL, ett sökvägssegment eller ett HTML-attribut. Det är hela anledningen till att korta länkar är Base62 och inte Base64.

“Vilken är mindre, Base62 eller Base64?”

För byte är Base64 något mindre: cirka 133 % av indatan mot cirka 134 %. På exemplet med 92 byte ovan slutar de två lika med 124 tecken. För decimala tal förkortar Base62 texten med cirka 44 %, och det är där den praktiska vinsten ligger.

“Kan jag avkoda en Base64-sträng med den här sidan?”

Nej, och det kommer inte att säga att det har misslyckats. De två alfabeten överlappar i alla 62 tecken, så en Base64-sträng är vanligtvis giltig indata här också och avkodas helt enkelt till ett annat tal. Använd Base64 för Base64.

“Har en Base62-kod en maximal längd?”

Nej, i teorin har algoritmen ingen övre gräns. I praktiken stannar den här sidan vid 4 096 decimala siffror, eller 2 048 byte, eftersom aritmetiken bakom den är kvadratisk och fliken skulle frysa utan något på skärmen som förklarar varför. Gränstabellen längre upp på sidan anger de uppmätta talen.

“Hur vet jag att resultatet på den här sidan är rätt?”

Tryck på Självtest. Det kör varje dokumenterat exempel, varje bytelängd från 0 till 64 och en spridning av decimala tal genom alla tre alfabet, jämför de returnerade värdena med det som skickades in, och kontrollerar på nytt att alla 62 tecken i varje alfabet är säkra i en URL. Knappen Exempel jämför dessutom sina tre resultat med värdena i sidans datafil, som verifierades mot en andra, oberoende implementering med stora heltal i webbplatsens testverktyg.

Standarder och källhänvisningar

Det finns ingen standard att implementera här: Base62 är en konvention, inte en specifikation, och de tre alfabeten som skrivs ut ovan är de som förekommer i verklig programvara. Den här sidan implementerar den med webbplatsens egna rutiner för stora heltal, skrivna som ren aritmetik på siffervektorer, så att ingen storlek någonsin begränsas av JavaScripts talsort.

Sidans text skrevs för den här webbplatsen. Varje exempel som förekommer på sidan togs fram av sidans egen kod och verifierades sedan mot en andra, oberoende implementering med inbyggda stora heltal, som finns kvar i webbplatsens testverktyg; samma implementering verifierade exempel- och storlekstabellerna i datafilen.