1. Ikhtisar
1.Apa itu Base64:
Base64 adalah salah satu metode pengkodean paling umum untuk mengirimkan kode byte 8-bit di Internet. Anda dapat memeriksa RFC2045~RFC2049, yang memiliki spesifikasi rinci untuk MIME. Pengkodean Base64 dapat digunakan untuk meneruskan informasi identifikasi yang lebih panjang di lingkungan HTTP. Misalnya, dalam sistem Persistensi Java Hibernate, Base64 digunakan untuk menyandikan pengidentifikasi unik yang panjang (biasanya UUID 128-bit) menjadi string, yang digunakan sebagai parameter dalam formulir HTTP dan URL GET HTTP. Dalam aplikasi lain, sering kali diperlukan pengkodean data biner ke dalam bentuk yang sesuai untuk ditempatkan di URL (termasuk bidang formulir tersembunyi). Saat ini, penggunaan pengkodean Base64 tidak hanya lebih pendek, tetapi juga tidak dapat dibaca, yaitu data yang dikodekan tidak akan langsung terlihat dengan mata telanjang.
2. Pendahuluan:
Standar Base64 tidak cocok untuk transmisi langsung di URL, karena pembuat enkode URL akan mengubah karakter "/" dan "+" di Base64 standar menjadi "%XX", dan karakter "%" ini ada Saat memasuki database , konversi lebih lanjut diperlukan karena tanda "%" telah digunakan sebagai karakter wildcard di ANSI SQL.
Untuk mengatasi masalah ini, pengkodean Base64 yang ditingkatkan untuk URL dapat digunakan, yang tidak menambahkan tanda '=' di akhir dan mengubah "+" dan "/" di Base64 standar menjadi "*" dan "-" masing-masing. , Ini menghilangkan kebutuhan untuk konversi selama pengkodean URL, decoding dan penyimpanan basis data, menghindari penambahan panjang informasi yang dikodekan dalam proses, dan menyatukan format pengidentifikasi objek dalam basis data, formulir, dll.
Ada juga varian Base64 yang ditingkatkan untuk ekspresi reguler, yang mengubah "+" dan "/" menjadi "!" dan "-" karena "+", "*" dan " Keduanya [" dan "]" mungkin memiliki arti khusus ekspresi reguler.
Ada juga varian yang mengubah "+/" menjadi "_-" atau "._" (digunakan sebagai pengenal nama dalam bahasa pemrograman) atau ".-" (digunakan untuk Nmtokens dalam XML) atau bahkan "_ :" (untuk Nama dalam XML).
Base64 memerlukan konversi setiap tiga byte 8Bit menjadi empat byte 6Bit (3*8 = 4*6 = 24), dan kemudian menambahkan dua bit 0 tinggi ke 6Bit untuk membentuk empat byte 8Bit, yaitu, string yang dikonversi secara teoritis akan menjadi 1/3 lebih panjang dari yang asli.
3. Aturan:
Aturan tentang pengkodean ini:
①.Ubah 3 karakter menjadi 4 karakter..
②.Tambahkan karakter baris baru setiap 76 karakter..
③.Terminator terakhir juga harus diproses..
Bukankah itu terlalu abstrak? Jangan khawatir, mari kita lihat contohnya:
Sebelum konversi: aaaaaabb ccccdddd eeffffff
Setelah konversi: 00aaaaa 00bbcccc 00ddddee 00ffffff
Seharusnya sudah jelas, bukan? Tiga byte teratas adalah teks asli, dan empat byte terbawah adalah pengkodean Base64 yang dikonversi, dengan dua bit pertama adalah 0.
Setelah konversi, kami menggunakan tabel kode untuk mendapatkan string yang kami inginkan (yaitu, pengkodean Base64 akhir)
2. Contoh kode implementasi Java:
kelas akhir publik Base64 { int akhir pribadi statis BASELENGTH = 255; int akhir pribadi statis LOOKUPLENGTH = 64; int akhir pribadi statis SIXTEENBIT = 16; = 6; final pribadi statis int FOURBYTE = 4; int SIGN = -128; karakter akhir pribadi statis PAD = '='; boolean akhir pribadi statis fDebug = false; byte pribadi akhir statis[] base64Alphabet = byte baru[BASELENGTH]; ]; statis { untuk (int i = 0; i < PANJANG DASAR; i++) { base64Alphabet[i] = -1; } untuk (int i = 'Z'; i >= 'A'; i--) { base64Alphabet[i] = (byte) (i - 'A'); i = 'z'; i >= 'a'; i--) { base64Alphabet[i] = (byte) (i - 'a' + 26); >= '0'; saya--) { base64Alphabet[i] = (byte) (i - '0' + 52); int i = 0; saya <= 25; i++) lookUpBase64Alphabet[i] = (karakter) ('A' + i); 26, j = 0; saya <= 51; i++, j++) lookUpBase64Alphabet[i] = (char) ('a' + j); untuk (int i = 52, j = 0; saya <= 61; i++, j++ ) lookUpBase64Alphabet[i] = (karakter) ('0' + j); lookUpBase64Alphabet[62] = (karakter) '+'; lookUpBase64Alphabet[63] = (char) '/'; } boolean statis yang dilindungi isWhiteSpace(char octect) { return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); boolean statis isPad(char oktet) { return (oktober == PAD); } isData boolean statis yang dilindungi(char oktet) { return (base64Alphabet[octect] != -1); boolean statis yang dilindungi isBase64(char oktet) { return (isWhiteSpace(octect) || isPad(octect) || isData(octect) ); } /** * Mengkodekan oktet hex ke dalam Base64 * * @param binerData * Array berisi binerData * @return Array Base64 yang dikodekan */ public static String encode(byte[] binerData) { if (binaryData == null) return null; int lengthDataBits = binerData.length * EIGHTBIT; ; } int lessThan24bits = lengthDataBits % TWENTYFOURBITGROUP; int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; int numberQuartet = lebih sedikit dari 24bit != 0 ? numberTriplets + 1 : numberTriplets; int numberLines = (numberQuartet - 1) / 19 + 1; char encodedData[] = null; = 0, aku = 0, b1 = 0, b2 = 0, b3 = 0; int encodedIndex = 0; int dataIndex = 0; int i = 0; if (fDebug) { System.out.println("jumlah kembar tiga = " + angkaTriplet); 0; baris < bilanganGaris - 1; baris++) { untuk (int kuartet = 0; kuartet < 19; kuartet++) { b1 = binerData[dataIndex++]; b2 = binerData[dataIndex++]; b3 = binerData[dataIndex++]; + b3); } l = (bita) (b2 & 0x0f); k = (bita) (b1 & 0x03); ((b1 & TANDA) == 0) ? (bita) (b1 >> 2) : (bita) ((b1) >> 2 ^ 0xc0); byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); byte val3 = ((b3 & TANDA) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); jika (fDebug) { System.out.println("val2 = " + val2); println("k4 = " + (k << 4)); Sistem.keluar.println("vak = " + (val2 | (k << 4)) } encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; lookUpBase64Alphabet[b3 & 0x3f]; } encodedData[encodedIndex++] = 0xa; } untuk (; i < numberTriplets; i++) { b1 = binerData[dataIndex++]; (fDebug) { Sistem.keluar.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3); } l = (bita) (b2 & 0x0f); k = (bita) (b1 & 0x03); = 0) ? (bita) (b1 >> 2) : (bita) ((b1) >> 2 ^ 0xc0); ((b2 & TANDA) == 0) ? (bita) (b2 >> 4) : (bita) ((b2) >> 4 ^ 0xf0); byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); Sistem.keluar.println("val2 = " + val2); Sistem.keluar.println("k4 = " + (k << 4)); Sistem.keluar.println("vak = " + (val2 | (k < < 4))); } Data yang disandikan[Indeks yang disandikan++] = lookUpBase64Alphabet[val1]; lookUpBase64Alphabet[val2 |.(k << 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; grup bit jika (kurang dari 24bit == DELAPANBIT) { b1 = binerData[dataIndeks]; k = (byte) (b1 & 0x03); jika (fDebug) { Sistem.keluar.println("b1=" + b1); " + (b1 >> 2)); } byte val1 = ((b1 & TANDA) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; encodedData[encodedIndex++] = PAD; if (kurang dari 24bit == ENAM BELAS) { b1 = binerData[dataIndeks]; b2 = binerData[dataIndeks + 1]; l = (bita) (b2 & 0x0f); == 0) ? (bita) (b1 >> 2) : (bita) ((b1) >> 2 ^ 0xc0); byte val2 = ((b2 & TANDA) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); ; 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; encodedData[encodedIndex++] = PAD; } encodedData[encodedIndex] = 0xa; * @param binerData * Array byte berisi data Base64 * @return Array berisi data yang didekodekan. */ public static byte[] decode(String dikodekan) { if (dikodekan == null) return null; char[] base64Data = dikodekan.toCharArray(); ); if (len % FOURBYTE != 0) { return null;// harus habis dibagi empat } int numberQuadruple = (len / FOURBYTE); jika (numberQuadruple == 0) mengembalikan byte baru[0]; byte decodedData[] = null; byte b1 = 0, b2 = 0, b4 = 0, marker0 = 0, marker1 = 0; d1 = 0, d2 = 0, d3 = 0, d4 = 0; int i = 0; int dikodekanIndex = 0; int dataIndex = 0; decodeData = byte baru[(numberQuadruple) * 3]; untuk (; 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); Data yang didekodekan[Indeks yang dikodekan++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); dikodekanIndex++] = (byte) (b3 << 6 | b4 } jika (!isData((d1 = base64Data[dataIndex++])) ||. ; d3 = base64Data[dataIndex++]; d4 = base64Data[dataIndex++]; (!isData((d3)) || !isData((d4))) {// Periksa apakah merupakan karakter PAD if (isPad(d3) && isPad(d4)) { // Dua PAD misalnya 3c[Pad][ Pad] if ((b2 & 0xf) != 0)// 4 bit terakhir harus nol mengembalikan byte[] tmp = byte baru[i * 3 + 1]; Sistem.arraycopy(data yang didekodekan, 0, tmp, 0, i * 3); tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); d3) && isPad(d4)) { // Satu PAD misalnya 3cQ[Pad] b3 = base64Alphabet[d3]; if ((b3 & 0x3) != 0)// 2 bit terakhir harus nol return byte[] tmp = new byte[i * 3 + 2]; tmp, 0, i * 3); tmp[dikodekanIndeks++] = (byte) (b1 << 2 | b2 >> 4); tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); return tmp; 3c[Pad]r", "3cdX", "3cXd", "3cXX" // dimana X bukan data } } else { // Tidak ada PAD misalnya 3cQl b3 = base64Alphabet[d3]; b4 = base64Alphabet[d4]; decodeData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); << 4) |.((b3 >> 2) & 0xf)); decodedData[encodedIndex++] = (byte) (b3 << 6 | b4 } return decodedData; } /** * hapus WhiteSpace dari MIME yang berisi data Base64 yang disandikan ) * @mengembalikan panjang baru */ protected static int deleteWhiteSpace(char[] data) { if (data == null) mengembalikan 0; // menghitung karakter yang tidak spasi int ukuran baru = 0; int len = data.panjang; untuk (int i = 0; i < len; i++) { if (!isWhiteSpace(data[i])) data[Ukuran baru++] = data[i]; } return newSize; } public static void main(String[] args) { System.out.println(encode("Republik Rakyat Tiongkok".getBytes()) }}