Codificação Java e JavaScript Base64
Ao desenvolver aplicativos da Web Java, você pode usar o Java para executar a codificação Base64 no lado do servidor e decodificá -lo em JavaScript no lado do cliente. Isso requer que os mecanismos de codificação Base64 de ambos os lados sejam consistentes.
O uso da codificação Base64 pode encontrar várias situações estranhas e até suspeita de que existem bugs na codificação. Mas, na verdade, esse não é o caso. O objeto que Base64 opera em teoria não é uma string, mas uma matriz de bytes. Seu princípio é reduzir os 255 caracteres do código ASCII a serem expressos em 64. Especificamente, os três bytes originais são representados por quatro bytes, e o comprimento aumenta até certo ponto após a codificação.
1) É melhor codificar imediatamente para evitar a codificação segmentada. É realmente necessário codificar a codificação segmentada. O número de bytes em cada segmento deve ser múltiplo de 3.
Para fluxos de bytes longos, se você deseja codificar durante a leitura, cada segmento deve ser um múltiplo de 3, caso contrário, poderá causar caos durante a restauração. A maioria das pessoas gosta de usar os multiplicadores de 2 para definir uma matriz, como byte [1024], porque não é um múltiplo de 3, pode ocorrer um erro durante a restauração. O exemplo correto é:
byte [] bs = novo byte [3*100] .... inputstream.read (bs) .. codifica (bs) ...
Para strings, geralmente é necessária toda a codificação para evitar erros de codificação segmentados.
Obviamente, se você codificar nos segmentos e restaurá -los um por um, não há problema.
2) Verifique se a string é restaurada de acordo com a codificação original ao restaurar a string.
Como opera em matrizes de bytes, os resultados são diferentes para caracteres chineses codificados por GBK e caracteres chineses codificados por UTF-8 após a codificação Base64. Por exemplo, se a palavra "nós" for um código GBK, será ztldxw == após ser convertido em base64; Se for o código UTF-8, ele será 5oir5Lus após ser convertido em base64.
Isso é "nós" ==》 getBytes ("gbk") ==> base64
Então, o que a codificação é usada para converter Java e o que a codificação é usada para restaurar o JavaScript. Para garantir que Java e JavaScript sejam universais, usamos a codificação do Unicode (é inconveniente converter JavaScript em UTF-8 e GBK, por isso usamos sua própria codificação de unicode). Os detalhes são os seguintes:
Lado do servidor:
1) Use GetBytes ("Unicode") para convertê -lo em uma matriz de bytes unicode.
2) codificar na string base64
3) Transfira para o cliente
Cliente:
1) Base64 é decodificado em matriz de bytes
2) Pressione Unicode para restaurar
O código é o seguinte (consulte o anexo para funções relacionadas):
Base64.Encode (Data, "Unicode"); // codificação final java
decode64 (dados); // decodificação de javascript
Anexo 1: Base64 Codificação em Java
pacote websharp.util; public class Base64 { private static final byte[] encodingTable = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/'}; byte final estático privado [] decodingtable; estático {decodingTable = new Byte [128]; for (int i = 0; i <128; i ++) {decodingTable [i] = (byte) -1; } para (int i = 'a'; i <= 'z'; i ++) {decodingTable [i] = (byte) (i - 'a'); } para (int i = 'a'; i <= 'z'; i ++) {decodingTable [i] = (byte) (i - 'a'+26); } para (int i = '0'; i <= '9'; i ++) {decodingTable [i] = (byte) (i - '0'+52); } decodingtable ['+'] = 62; decodingtable ['/'] = 63; } public static byte [] codifica (byte [] dados, int offset) {byte [] bytes; int realCount = Data.Length-Offset; int modulus = realCount % 3; if (modulus == 0) {bytes = novo byte [(4 * realCount) / 3]; } else {bytes = novo byte [4 * ((realCount / 3) + 1)]; } int datalength = (data.length - modulus); int a1; int a2; int a3; for (int i = deslocamento, j = 0; i <comprimento do datal; i += 3, j += 4) {a1 = dados [i] & 0xff; A2 = dados [i + 1] & 0xff; A3 = dados [i + 2] & 0xff; bytes [j] = codingTable [(a1 >>> 2) & 0x3f]; bytes [j + 1] = codingTable [((a1 << 4) | (a2 >>> 4)) e 0x3f]; bytes [j + 2] = codingTable [((a2 << 2) | (a3 >>> 6)) e 0x3f]; bytes [j + 3] = codingtable [a3 & 0x3f]; } int b1; int b2; int b3; int d1; int d2; Switch (Modulus) {case 0: / * Nada mais a fazer * / break; Caso 1: d1 = dados [data.length - 1] & 0xff; b1 = (d1 >>> 2) & 0x3f; b2 = (d1 << 4) & 0x3f; bytes [bytes.length - 4] = codingtable [b1]; bytes [bytes.length - 3] = codingtable [b2]; bytes [bytes.length - 2] = (byte) '='; bytes [bytes.length - 1] = (byte) '='; quebrar; Caso 2: d1 = dados [data.length - 2] & 0xff; d2 = dados [data.length - 1] & 0xff; b1 = (d1 >>> 2) & 0x3f; b2 = ((d1 << 4) | (d2 >>> 4)) e 0x3f; b3 = (d2 << 2) & 0x3f; bytes [bytes.length - 4] = codingtable [b1]; bytes [bytes.length - 3] = codingtable [b2]; bytes [bytes.length - 2] = codingTable [b3]; bytes [bytes.length - 1] = (byte) '='; quebrar; } retornar bytes; } public static byte [] decodge (byte [] dados) {byte [] bytes; byte B1; byte b2; byte B3; byte B4; dados = descarteNonBase64Bytes (dados); if (data [data.length - 2] == '=') {bytes = novo byte [(((data.length / 4) - 1) * 3) + 1]; } else if (data [data.length - 1] == '=') {bytes = novo byte [((data.length / 4) - 1) * 3) + 2]; } else {bytes = novo byte [((data.length / 4) * 3)]; } para (int i = 0, j = 0; i <(data.length - 4); i += 4, j += 3) {b1 = decodingTable [Data [i]]; b2 = decodingtable [dados [i + 1]]; b3 = decodingtable [dados [i + 2]]; b4 = decodingtable [dados [i + 3]]; bytes [j] = (byte) ((b1 << 2) | (b2 >> 4)); bytes [j + 1] = (byte) ((b2 << 4) | (b3 >> 2)); bytes [j + 2] = (byte) ((b3 << 6) | b4); } if (data [data.length - 2] = '=') {b1 = decodingTable [data [data.length - 4]]; b2 = decodingtable [data [data.length - 3]]; bytes [bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4)); } else if (data [data.length - 1] == '=') {b1 = decodingTable [data [data.length - 4]]; b2 = decodingtable [data [data.length - 3]]; b3 = decodingtable [data [data.length - 2]]; bytes [bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4)); bytes [bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2)); } else {b1 = decodingTable [data [data.length - 4]]; b2 = decodingtable [data [data.length - 3]]; b3 = decodingtable [data [data.length - 2]]; b4 = decodingtable [data [data.length - 1]]; bytes [bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4)); bytes [bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2)); bytes [bytes.length - 1] = (byte) ((b3 << 6) | b4); } retornar bytes; } public static byte [] decodge (string data) {byte [] byte b1; byte b2; byte B3; byte B4; dados = descarteNonBase64Chars (dados); if (data.charat (data.length () - 2) == '=') {bytes = novo byte [(((data.length () / 4) - 1) * 3) + 1]; } else if (data.charat (data.length () - 1) == '=') {bytes = new byte [((data.length () / 4) - 1) * 3) + 2]; } else {bytes = novo byte [((data.length ()) / 4) * 3)]; } para (int i = 0, j = 0; i <(data.length () - 4); i += 4, j += 3) {b1 = decodingTable [data.charat (i)]; b2 = decodingtable [data.charat (i + 1)]; b3 = decodingtable [data.charat (i + 2)]; b4 = decodingtable [data.charat (i + 3)]; bytes [j] = (byte) ((b1 << 2) | (b2 >> 4)); bytes [j + 1] = (byte) ((b2 << 4) | (b3 >> 2)); bytes [j + 2] = (byte) ((b3 << 6) | b4); } if (data.charat (data.length () - 2) == '=') {b1 = decodingTable [data.charat (data.length () - 4)]; b2 = decodingtable [data.charat (data.length () - 3)]; bytes [bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4)); } else if (data.charat (data.length () - 1) == '=') {b1 = decodingTable [data.charat (data.length () - 4)]; b2 = decodingtable [data.charat (data.length () - 3)]; b3 = decodingtable [data.charat (data.length () - 2)]; bytes [bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4)); bytes [bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2)); } else {b1 = decodingTable [data.charat (data.length () - 4)]; b2 = decodingtable [data.charat (data.length () - 3)]; b3 = decodingtable [data.charat (data.length () - 2)]; b4 = decodingtable [data.charat (data.length () - 1)]; bytes [bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4)); bytes [bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2)); bytes [bytes.length - 1] = (byte) ((b3 << 6) | b4); } para (int i = 0; i <bytes.length; i ++) system.out.println (","+bytes [i]); retornar bytes; } byte estático privado [] descartNonBase64Bytes (byte [] dados) {byte [] temp = new byte [data.length]; int byTescopied = 0; for (int i = 0; i <data.length; i ++) {if (isValidBase64Byte (dados [i])) {temp [byTescopied ++] = dados [i]; }} byte [] newData = novo byte [bytescopied]; System.arraycopy (temp, 0, newData, 0, bytescopied); retornar newData; } String estática privada DispardNonBase64Chars (String Data) {StringBuffer sb = new StringBuffer (); int length = data.length (); for (int i = 0; i <comprimento; i ++) {if (isValidBase64Byte ((byte) (data.charat (i)))) {sb.append (data.charat (i)); }} return sb.toString (); } private estático booleano isValidBase64byte (byte b) {if (b == '=') {return true; } else if ((b <0) || (b> = 128)) {return false; } else if (decodingTable [b] == -1) {return false; } retornar true; } public static string cody (dados da string, string charset) lança a exceção {// byte [] resultado = (data.getBytes ("unicode")); if (data == null || data.length () == 0) retorna dados; int offset = 0; // Depois de GettingBytes ("Unicode") é girado, dois bytes "Fe" serão adicionados ao byte frontal [] resultado = Encode (data.getBytes (charset), deslocamento); StringBuffer sb = new StringBuffer (resultado.length); for (int i = 0; i <resultado.length; i ++) sb.append ((char) resultado [i]); return sb.toString (); } public static string decode (dados da string, string charset) lança a exceção {if (data == null || data.length () == 0) retorna dados; return new string (base64.decode (dados), charset); } public static void main (string [] args) lança exceção {string data = "nós"; String data1 = codificador (dados, "unicode"); String data2 = decodificação (data1, "unicode"); System.out.println (dados); System.out.println (Data1); System.out.println (Data2); }} Apêndice 2: Base64 Codificação em JavaScript
<html> <head> <title>base64 Encoding/Decoding</title> </head> <script type="text/javascript"><!-- var keyStr = "ABCDEFGHIJKLMNOP" + "QRSTUVWXYZabcdef" + "ghijklmnopqrstuv" + "wxyz0123456789+/" + "="; function cody64 (input) {input = unicodetobytes (entrada); var output = ""; var Chr1, Chr2, Chr3 = ""; var enc1, ENC2, ENC3, ENC4 = ""; var i = 0; do {Chr1 = entrada [i ++]; Chr2 = entrada [i ++]; Chr3 = entrada [i ++]; ENC1 = Chr1 >> 2; ENC2 = ((Chr1 e 3) << 4) | (Chr2 >> 4); Enc3 = ((Chr2 e 15) << 2) | (Chr3 >> 6); ENC4 = Chr3 e 63; if (isnan (Chr2)) {Enc3 = Enc4 = 64; } else if (isnan (Chr3)) {Enc4 = 64; } output = output + keystr.charat (ENC1) + keystr.charat (ENC2) + keystr.charat (ENC3) + keystr.charat (ENC4); Chr1 = Chr2 = Chr3 = ""; ENC1 = ENC2 = ENC3 = ENC4 = ""; } while (i <input.length); saída de retorno; } função decode64 (input) {var output = ""; var Chr1, Chr2, Chr3 = ""; var enc1, ENC2, ENC3, ENC4 = ""; var i = 0; // Remova todos os caracteres que não são AZ, AZ, 0-9, +,/, OR = var BASE64TEST =/[^a-za-z0-9/ +/// =]/g; if (base64test.exec (input)) {alert ("Havia caracteres Base 64 inválidos no texto de entrada./n" + "Os caracteres Base64 válidos são AZ, AZ, 0-9, ' +', '/' e '='/n" + "esperam erros na decodificação."); } input = input.replace (/[^a-za-z0-9/+/// =]/g, ""); output = new Array (); do {Enc1 = keystr.indexOF (input.charat (i ++)); Enc2 = keystr.IndexOF (input.Charat (i ++)); Enc3 = keystr.IndexOF (input.Charat (i ++)); ENC4 = keystr.IndexOF (input.Charat (i ++)); Chr1 = (ENC1 << 2) | (ENC2 >> 4); Chr2 = ((Enc2 e 15) << 4) | (Enc3 >> 2); Chr3 = ((Enc3 e 3) << 6) | ENC4; output.push (Chr1); if (Enc3! = 64) {output.push (Chr2); } if (Enc4! = 64) {output.push (Chr3); } Chr1 = Chr2 = Chr3 = ""; ENC1 = ENC2 = ENC3 = ENC4 = ""; } while (i <input.length); retornar bytestounicode (saída); } função unicodetobytes (s) {var resultado = new Array (); if (s == NULL || S == "") RECULTE RESULTADO; resultado.push (255); // Adicione "Fe" ao resultado da cabeça.push (254); for (var i = 0; i <comprimento; i ++) {var c = s.charcodeat (i) .ToString (16); if (c.Length == 1) i = "000"+c; caso contrário, if (c.Length == 2) c = "00"+c; else if (c.Length == 3) c = "0"+c; var var1 = parseint (c.substring (2), 16); var var2 = parseint (c.substring (0,2), 16); resultado.push (var1); resultado.push (var2); } resultado de retorno; } função bytestounicode (bs) {var resultado = ""; var offset = 0; if (bs.length> = 2 && bs [0] == 255 && bs [1] == 254) deslocamento = 2; // exclua "fe" para (var i = deslocamento; i <bs.length; i+= 2) {var code = bs [i]+(bs [i+1] << 8); resultado+= string.fromCharcode (código); } resultado de retorno; } //-> </script> <body> <formulário name = "base64form"> digite a mensagem que deseja codificar em base64 ou colar <br> base64 Texto codificado no campo de texto, selecione codificar ou decodificar, <br> e clique no botão! <br> <textarea name = "thetext" cols = "40 40" 40 "e <br> e clique no botão! name = "Encode" value = "Encode para base64" onclick = "document.base64form.thetext.value = code64 (document.base64form.thetext.value);"> <input type = "button" name = "decode" value = "decode de base64" OnClick = "document.base64form.thetext.value = decode64 (document.base64form.thetext.value);"> </morm> </body> </html>Obrigado pela leitura, espero que isso possa ajudá -lo. Obrigado pelo seu apoio a este site!