1. Übersicht
1.Was ist Base64:
Base64 ist eine der gebräuchlichsten Kodierungsmethoden für die Übertragung von 8-Bit-Bytecodes im Internet. Sie können sich RFC2045 bis RFC2049 ansehen, das detaillierte Spezifikationen für MIME enthält. Die Base64-Kodierung kann verwendet werden, um längere Identifikationsinformationen in einer HTTP-Umgebung zu übergeben. Beispielsweise wird im Java-Persistenzsystem Hibernate Base64 verwendet, um eine lange eindeutige Kennung (normalerweise eine 128-Bit-UUID) in eine Zeichenfolge zu kodieren, die als Parameter in HTTP-Formularen und HTTP-GET-URLs verwendet wird. In anderen Anwendungen ist es häufig erforderlich, Binärdaten in eine Form zu kodieren, die für die Platzierung in einer URL geeignet ist (einschließlich versteckter Formularfelder). Zu diesem Zeitpunkt ist die Verwendung der Base64-Codierung nicht nur kürzer, sondern auch unlesbar, dh die codierten Daten sind mit bloßem Auge nicht direkt sichtbar.
2. Einführung:
Standard-Base64 ist nicht für die Übertragung direkt in der URL geeignet, da der URL-Encoder die Zeichen „/“ und „+“ im Standard-Base64 in die Form „%XX“ ändert und diese „%“-Zeichen beim Betreten der Datenbank vorhanden sind ist eine weitere Konvertierung erforderlich, da das „%“-Zeichen in ANSI SQL als Platzhalterzeichen verwendet wurde.
Um dieses Problem zu lösen, kann eine verbesserte Base64-Codierung für URLs verwendet werden, die das „=“-Zeichen am Ende nicht auffüllt und das „+“ und „/“ im Standard-Base64 in „*“ bzw. „-“ ändert. , Dadurch entfällt die Notwendigkeit einer Konvertierung während der URL-Kodierung, Dekodierung und Datenbankspeicherung, es wird vermieden, dass die Länge der kodierten Informationen im Prozess zunimmt, und das Format von Objektkennungen in Datenbanken, Formularen usw. wird vereinheitlicht.
Es gibt auch eine verbesserte Base64-Variante für reguläre Ausdrücke, die „+“ und „/“ in „!“ und „-“ ändert, da „+“, „*“ und „ Sowohl [“ als auch „]“ eine besondere Bedeutung haben können reguläre Ausdrücke.
Es gibt auch Varianten, die „+/“ in „_-“ oder „._“ (wird als Bezeichnernamen in Programmiersprachen verwendet) oder „.-“ (wird für Nmtokens in XML verwendet) oder sogar „_ :“ (für Name) ändern in XML).
Base64 erfordert die Konvertierung aller drei 8-Bit-Bytes in vier 6-Bit-Bytes (3 * 8 = 4 * 6 = 24) und das anschließende Hinzufügen von zwei High-Bit-0s zum 6-Bit, um vier 8-Bit-Bytes zu bilden. Das heißt, die konvertierte Zeichenfolge wird theoretisch sein 1/3 länger als das Original.
3. Regeln:
Regeln zu dieser Kodierung:
①.Konvertieren Sie 3 Zeichen in 4 Zeichen.
②.Fügen Sie alle 76 Zeichen ein Zeilenumbruchzeichen hinzu.
③.Der letzte Terminator muss ebenfalls verarbeitet werden.
Ist das nicht zu abstrakt? Keine Sorge, schauen wir uns ein Beispiel an:
Vor der Konvertierung: aaaaaabb ccccdddd eeffffff
Nach der Konvertierung: 00aaaaaa 00bbcccc 00ddddee 00ffffff
Es sollte klar sein, oder? Die oberen drei Bytes sind der Originaltext und die unteren vier Bytes sind die konvertierte Base64-Kodierung, wobei die ersten beiden Bits 0 sind.
Nach der Konvertierung verwenden wir eine Codetabelle, um die gewünschte Zeichenfolge zu erhalten (d. h. die endgültige Base64-Codierung).
2. Beispiel für einen Java-Implementierungscode:
public final class Base64 { static private final int BASELENGTH = 64; static private final int EIGHTBIT = 16; static private final int = 6; static private final int FOURBYTE = 4; int SIGN = -128; static private final char PAD = '='; static private final byte[] base64Alphabet = new byte[BASELENGTH]; ]; static { for (int i = 0; i < BASELENGTH; i++) { base64Alphabet[i] = -1; } for (int i = 'Z'; i >= 'A'; i--) { base64Alphabet[i] = (byte) (i - 'A'); i = 'z'; i >= 'a'; i--) { base64Alphabet[i] = (byte) (i - 'a' + 26 } for (int i = '9'; i >= '0'; i--) { base64Alphabet[i] = (byte) (i - '0' + 52 } base64Alphabet['/'] = 63; int i = 0; i <= 25; i++) lookUpBase64Alphabet[i] = (char) ('A' + i); 26, j = 0; i <= 51; i++, j++) lookUpBase64Alphabet[i] = (char) ('a' + j); for (int i = 52, j = 0; i <= 61; i++, j++ ) lookUpBase64Alphabet[i] = (char) ('0' + j); lookUpBase64Alphabet[62] = (char) '+'; lookUpBase64Alphabet[63] = (char) '/'; } protected static boolean isWhiteSpace(char octect) { return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); static boolean isPad(char octect) { return (octect == PAD); } protected static boolean isData(char octect) { return (base64Alphabet[octect] != -1); } protected static boolean isBase64(char octect) { return (isWhiteSpace(octect) || isPad(octect) || isData(octect) ); } /** * Codiert Hex-Oktate in Base64 * * @param BinaryData * Array mit BinaryData * @return Encoded Base64 Array */ public static String encode(byte[] BinaryData) { if (binaryData == null) return null; if (lengthDataBits == 0) { return "" ; } int lesserThan24bits = lengthDataBits % int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; int numberQuartet = lessThan24bits != 0 ? numberTriplets = (numberQuartet - 1) / 19 + 1; char encodedData[] = null; encodedData = new char[numberQuartet * 4 + numberLines] = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; int encodedIndex = 0; int i = 0; if (fDebug) { System.out.println("number of triplets = " + numberTriplets); 0; line < numberLines - 1; line++) { for (int quartet = 0; quartet < 19; quartet++) { b1 = binäreDaten[DatenIndex++]; b3 = BinäreDaten[DatenIndex++]; if (fDebug) { System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3); } l = (Byte) (b2 & 0x0f); k = (Byte) (b1 & 0x03); ((b1 & SIGN) == 0) ? (Byte) (b1 >> 2) : (Byte) ((b1) >> 2 ^ 0xc0); Byte) (b2 >> 4) : (Byte) ((b2) >> 4 ^ 0xf0); Byte val3 = ((b3 & SIGN) == 0) ? (Byte) (b3 >> 6) : (Byte) ((b3) >> 6 ^ 0xfc); if (fDebug) { System.out.println("val2 = " + val2); println("k4 = " + (k << 4)); System.out.println("vak = " + (val2 | (k << 4)) } encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; lookUpBase64Alphabet[b3 & 0x3f]; i++ } encodedData[encodedIndex++] = 0xa; (fDebug) { System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3); } l = (byte) (b2 & 0x0f); k = (byte) (b1 & 0x03); = 0) ? (Byte) (b1 >> 2) : (Byte) ((b1) >> 2 ^ 0xc0); ((b2 & SIGN) == 0) ? (Byte) (b2 >> 4) : (Byte) ((b2) >> 4 ^ 0xf0); Byte) (b3 >> 6) : (Byte) ((b3) >> 6 ^ 0xfc); System.out.println("val2 = " + val2); System.out.println("k4 = " + (k << 4)); System.out.println("vak = " + (val2 | (k < < 4))); } encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; lookUpBase64Alphabet[val2 |. (k << 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | Bitgruppen if (fewerThan24bits == EIGHTBIT) { b1 = BinaryData[dataIndex]; k = (byte) (b1 & 0x03); if (fDebug) { System.out.println("b1<<2 = " + (b1 >> 2)); } Byte val1 = ((b1 & SIGN) == 0) ? (Byte) (b1 >> 2) : (Byte) ((b1) >> 2 ^ 0xc0); encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; encodedData[encodedIndex++] = PAD; if (weniger als 24 Bit == SIXTEENBIT) { b1 = Binärdaten[DatenIndex]; l = (Byte) (b2 & 0x0f); == 0) ? (Byte) (b1 >> 2) : (Byte) ((b1) >> 2 ^ 0xc0); byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); encodedData[encodedIndex++] = lookUpBase64Alphabet[val1] ; encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; encodedData[encodedIndex] = 0xa; return new String(encodedData); * @param BinaryData * Byte-Array mit Base64-Daten * @return Array mit Base64-Daten dekodierte Daten. */ public static byte[] decode(String encoded) { if (encoded == null) return null; ); if (len % FOURBYTE != 0) { return null;// sollte durch vier teilbar sein } int numberQuadruple = (len / FOURBYTE); if (numberQuadruple == 0) return new byte[0]; byte decodedData[] = null, b2 = 0, b3 = 0, marker1 = 0; d1 = 0, d2 = 0, d3 = 0, d4 = 0; int i = 0; = 0; int dataIndex = 0; decodedData = new byte[(numberQuadruple) * 3]; for (; i < numberQuadruple - 1; i++) { if (!isData((d1 = base64Data[dataIndex++])) || !isData ((d2 = base64Data[dataIndex++])) || base64Data[dataIndex++])) || = base64Alphabet[d3]; b4 = base64Alphabet[d4]; = (Byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); encodedIndex++] = (byte) (b3 << 6 | b4); } if (!isData((d1 = base64Data[dataIndex++])) ||. ; d3 = base64Data[dataIndex++]; d4 = base64Data[dataIndex++]; (!isData((d3)) || !isData((d4))) {// Überprüfen Sie, ob es sich um PAD-Zeichen handelt if (isPad(d3) && isPad(d4)) { // Zwei PAD, z. B. 3c[Pad][ Pad] if ((b2 & 0xf) != 0)// letzte 4 Bits sollten Null sein return null; 1]; System.arraycopy(decodedData, 0, i * 3); tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); d3) && isPad(d4)) { // Ein PAD, zB 3cQ[Pad] b3 = base64Alphabet[d3]; if ((b3 & 0x3) != 0)// letzte 2 Bits sollten Null sein return null; tmp, 0, i * 3); tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); 3c[Pad]r", "3cdX", "3cXd", "3cXX" // wobei X keine Daten ist } } else { // Kein PAD, z. B 3cQl b3 = base64Alphabet[d3]; b4 = base64Alphabet[d4]; decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) |. ((b3 >> 2) & 0xf)); decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); return decodedData; } /** * WhiteSpace aus MIME entfernen, das codierte Base64-Daten enthält (mit WS ) * @return the new length */ protected static int removeWhiteSpace(char[] data) { if (data == null) return 0; // count Zeichen, die nicht sind whitespace int newSize = 0; int len = data.length; for (int i = 0; i < len; i++) { if (!isWhiteSpace(data[i])) data[newSize++] = data[i]; } return newSize; } public static void main(String[] args) { System.out.println(encode("Volksrepublik China".getBytes()) }}