środa, maja 20, 2020

Czasem człowiek musi napisać dekodowanie Base64 w JavaScript ;-)

Tak, wiem, że JavaScript w przeglądarce to ma, wystarczy użyć metody atob.
Ale ja postanowiłem sobie zrobić skrypt do Keyboard Maestro, który po tym jak sobie zaznaczę w przeglądarce token JWT i wcisnę jakąś kombinację klawiszy (na razie ALT-CMD-SHIFT-J) to mi zdekoduje ten token i go wyświetli.
JWT jest w Base64 i w sieci można łatwo znaleźć kod do jego rozkodowania....

No i wziąłem ten kod, tylko że okazało się, że JavaScript for Automation w macOS nie ma metody atob, która przerabia Base64 w tekst ;-)

Base64 jest proste, idea jest taka, że mamy 64 znaki, wielkie litery, małe litery, cyfry i w końcu + i /.
Mają wartości od 0 dla A do 63 dla /.
Czyli możemy tak zakodować 6 bitów :-)

Normalny znak ma 8 bitów ;-)

Więc 4 znaki z Base64 to 24 bity, czyli 3 znaki ASCII :-)

Czyli jak chcemy zdekodować jakiś tekst to bierzemy sobie liczbę, którą ustawiamy na 0, teraz robimy tak tą liczbę przesuwamy o 6 bitów w lewo, dodajemy do niej liczbę którą reprezentuje pobrany znak, i pobieramy następny znak, znów przesuwamy o 6 bitów i dodajemy... i powtarzamy to 4 razy.
Mamy 24 bity. Teraz przesuwamy najstarsze 8 bitów w prawo o 16 bitów i robimy and z 0xFF, i mamy pierwszy zakodowany znak ;-) bierzemy "środkowe" 8 bitów i przesuwamy je o 8 bitów w prawo i znów and z 0xFF i mamy drugi znak i w końcu robimy and 0xFF i mamy 3 znak :-)

Do tego trzeba pamiętać, że jak mamy = to po prostu przesuwamy bity (mogliby to równie dobrze zastąpić A ;-)

Mój kod nie jest jakiś szczególnie optymalny, ale chodziło mi o to by po prostu działał i wygląda tak ;-)
function f2t(z) {
var t = "";
var a = (z&(255<<16))>>16;
var b = (z&(255<<8))>>8;
var c = (z&255);
if (a!=0) t+=String.fromCharCode(a);
if (b!=0) t+=String.fromCharCode(b);
if (c!=0) t+=String.fromCharCode(c);
return t;
}

function _atob(base64) {
var t = "";
var z = 0;
var j = 0;
for (var i=0; i<base64.length; i++) {
var c = base64.charAt(i);
z<<=6;
if (c=='=') continue;
z+=b.indexOf(c);
j++;
if (j==4) {
t+=f2t(z);
z=0;
j=0;
}
}
t+=f2t(z);
return t;
}



Podobne postybeta
Raspberry Pi + no-ip.org ;-)
Lenie ;-)
Z NMEA do KML (chyba najbardziej kryptyczny tytuł postu jak stworzyłem ;-))
2016 będzie rokiem "nietypowym"
Spectre powinno działać nawet w Java'ie ;-)

Brak komentarzy:

Publikowanie komentarza