Dies ist eine Fortsetzung der Kommentare in der ursprünglichen Frage. Es endete viel länger als ich erwartet hatte; also in den Antwortabschnitt verschoben.
bc
ist ein numerischer Prozessor, der mit einer beliebigen Basis umgehen kann; jedoch aus dem bc Command Manual :
Bei Basen, die größer als 16 sind, bc
werden die Zahlen mit einer aus mehreren Zeichen bestehenden Zahl gedruckt, wobei jede höhere Basisziffer als Basisnummer 10 gedruckt wird. Die aus mehreren Zeichen bestehenden Ziffern sind durch Leerzeichen getrennt.
(Eine ähnliche Aussage erscheint auf der Manpage von bc .)
Was wir "base64" nennen, ist eine spezielle Zuordnung von Zeichen zu jedem der 64 Werte. (Siehe den Wikipedia-Artikel zu Base64 .)
Die Darstellung von "0" bc
wäre "0"; wohingegen die tatsächliche Basis64 "A" ist.
Die Ausgabe Ihres vorgeschlagenen Befehls bc lautet:
$ echo "obase=64; ibase=16; 5C78336D77D8DF448007D277DAD5C569" | bc 01 28 30 03 13 45 29 61 35 31 17 08 00 07 52 39 31 26 53 28 21 41
Wenn also bc
Ausgaben ausgegeben werden 01 28 30 03 . . .
, warum können wir nicht einfach die Werte für 01, 28, 30 usw. in der Tabelle nachschlagen (was "B", "c" und "e" ergibt, was sich von "XHg" unterscheidet … "Das erwartet Sie)?
Lassen Sie uns zunächst das Problem vereinfachen.
Wenn wir einen kürzeren String eingeben bc
, wie beispielsweise nur die ersten 2,5 Bytes, sieht die Ausgabe ähnlich aus:
$ echo "obase=64; ibase=16; 5C783" | bc 01 28 30 03
Eine noch kürzere Saite ist jedoch völlig anders:
$ echo "obase=64; ibase=16; 5C78" | bc 05 49 56
Warum das? Ihre ursprüngliche Zeichenfolge bestand aus 32 Zeichen (2 ^ 4 * 32; 2 ^ 128), die in 64 (2 ^ 6) unterteilt sind und 22 Zeichen (22 * 6 = 132) mit einem Rest von 4 erfordern. Dieser Rest ist wichtig, wenn man die Ausgabe von betrachtet, bc
aber nicht wirklich etwas anderes.
Die 4-stellige Eingabezeichenfolge hat 2 ^ 16 Werte. Durch 64 (2 ^ 6) dividiert, kann es in drei 64-Bit-Wörter passen (wobei 2 Bits übrig bleiben). Die 5-stellige Eingabezeichenfolge hat jedoch 2 ^ 20 Werte. Durch 2 ^ 6 dividiert, sind vier Wörter erforderlich (vier verbleibende Bits; derselbe Rest wie in der ursprünglichen Zeichenfolge).
Ein noch kürzerer Eingangswert (5C) hat auch den gleichen Rest (2 ^ 8/2 ^ 6 = 2 + 4 Bit).
$ echo "obase=64; ibase=16; 5C" | bc 01 28
Wenn Sie dieses "Feature" von verwenden bc
, können wir die ersten beiden Zeichen verwenden, um eine einfache Beschreibung der tatsächlichen Vorgänge zu entwickeln.
5C
in binär ist 01011100
. In der base64-Welt betrachten wir die ersten 6 Bits ( 010111
oder dezimal 23) und sehen in der Wikipedia-Tabelle, 23 ist eigentlich X
. Großartig! Es entspricht dem, was Sie erwarten! Wir fuhren dann mit jeweils sechs Bits durch den String.
Auf der anderen Seite, woher kommt die 01 28? Zurück zum binären 01011100
. Im Gegensatz zu der base64-Prozedur, die am Anfang des Strings beginnt und "=" bis zum Ende auflädt, gibt bc bei einem Rest (die Anzahl der base16-Zeichen ist kein Vielfaches von 3) an 0 an der Eingabewert. Mit dem vorgenannten Rest von 4 wird bc also tatsächlich arbeiten 0000 01011100
; und in 6-Bit-Chunks (base64) endet dies als 000001 011100
Dezimalwert von 01 und 28.
Wenn Sie das Ende der Eingabezeichenfolge mit bc so füllen, dass die Länge ein Vielfaches von drei ist, erhalten Sie etwas, das der gewünschten Ausgabe ähnelt:
$ echo "obase=64; ibase=16; 5C78336D77D8DF448007D277DAD5C5690" | bc 23 07 32 51 27 23 31 24 55 52 18 00 01 61 09 55 54 45 23 05 26 16
Sie müssen immer noch 23 = X
, 07 = H
, 32 = g
usw. in der Tabelle nachschlagen .