Java y JavaScript Base64 Codificación
Al desarrollar aplicaciones web de Java, puede usar Java para realizar una codificación Base64 en el lado del servidor y decodificarlo en JavaScript en el lado del cliente. Esto requiere que los mecanismos de codificación Base64 en ambos lados sean consistentes.
El uso de la codificación Base64 puede encontrar varias situaciones extrañas, e incluso sospechar que hay errores en la codificación. Pero de hecho, este no es el caso. El objeto que Base64 opera en teoría no es una cadena sino una matriz de bytes. Su principio es reducir los 255 caracteres del código ASCII que se expresarán en 64. Específicamente, los tres bytes originales están representados por cuatro bytes, y la longitud aumenta hasta cierto punto después de la codificación.
1) Es mejor codificar a la vez para evitar la codificación segmentada. De hecho, es necesario codificar la codificación segmentada. El número de bytes en cada segmento debe ser múltiplos de 3.
Para flujos de bytes largos, si desea codificar mientras lee, cada segmento debe ser un múltiplo de 3, de lo contrario puede causar caos durante la restauración. A la mayoría de las personas les gusta usar los multiplicadores de 2 para definir una matriz, como Byte [1024], porque no es un múltiplo de 3, puede ocurrir un error durante la restauración. El ejemplo correcto es:
byte [] bs = nuevo byte [3*100] .... inputstream.read (bs) .. code (bs) ...
Para las cadenas, la codificación completa generalmente se requiere para evitar errores de codificación segmentados.
Por supuesto, si codifica en segmentos y los restaura uno por uno, no hay problema.
2) Asegúrese de que la cadena se restablezca de acuerdo con la codificación original al restaurar la cadena.
Debido a que funciona en matrices de bytes, los resultados son diferentes para los caracteres chinos codificados por GBK y los caracteres chinos codificados por UTF-8 después de la codificación Base64. Por ejemplo, si la palabra "nosotros" es código GBK, será ztldxw == después de convertirse a base64; Si es el código UTF-8, será 5OIR5LUS después de convertirse en Base64.
Eso es "nosotros" ==》 getBytes ("gbk") ==> base64
Entonces, qué codificación se usa para convertir Java y qué codificación se usa para restaurar JavaScript. Para garantizar que Java y JavaScript sean universales, utilizamos la codificación de Unicode (es inconveniente convertir JavaScript en UTF-8 y GBK, por lo que utilizamos su propia codificación de Unicode). Los detalles son los siguientes:
Lado del servidor:
1) Use GetBytes ("Unicode") para convertirlo en una matriz de bytes unicode.
2) Codificar en la cadena Base64
3) Transferir al cliente
Cliente:
1) Base64 se decodifica en la matriz de bytes
2) Presione Unicode para restaurar
El código es el siguiente (ver archivo adjunto para funciones relacionadas):
Base64.encode (datos, "unicode"); // codificación de Java End
decode64 (datos); // decodificación de JavaScript
Adjunto 1: Base64 Codificación en Java
paquete 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), (byte), (byte), (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) ((byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g' g ', (byte)' h ', (byte)' i ', (byte)' j ', (byte)' k 'k' ', (byte)' l ', (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) (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/'}; byte final estático privado [] decodingtable; static {decodingtable = new byte [128]; para (int i = 0; i <128; i ++) {decodingtable [i] = (byte) -1; } for (int i = 'a'; i <= 'z'; i ++) {decodingTable [i] = (byte) (i - 'a'); } for (int i = 'a'; i <= 'z'; i ++) {decodingTable [i] = (byte) (i - 'a'+26); } for (int i = '0'; i <= '9'; i ++) {decodingTable [i] = (byte) (i - '0'+52); } decodingtable ['+'] = 62; decodingtable ['/'] = 63; } public static byte [] code (byte [] data, int offset) {byte [] bytes; int realCount = data.length-offset; int modulus = RealCount % 3; if (modulus == 0) {bytes = new Byte [(4 * RealCount) / 3]; } else {bytes = new Byte [4 * ((RealCount / 3) + 1)]; } int dataLength = (data.length - modulus); int a1; int a2; int a3; for (int i = offset, j = 0; i <dataLength; i += 3, j += 4) {a1 = data [i] & 0xff; a2 = datos [i + 1] & 0xff; a3 = datos [i + 2] y 0xff; bytes [j] = EncodingTable [(a1 >>> 2) y 0x3f]; bytes [j + 1] = EncodingTable [((a1 << 4) | (a2 >>> 4)) y 0x3f]; bytes [j + 2] = EncodingTable [((a2 << 2) | (a3 >>> 6)) y 0x3f]; bytes [j + 3] = EncodingTable [a3 y 0x3f]; } int b1; int b2; int b3; int d1; int d2; switch (módulo) {case 0: / * no queda nada que hacer * / rompa; caso 1: d1 = data [data.length - 1] & 0xff; b1 = (d1 >>> 2) y 0x3f; b2 = (d1 << 4) y 0x3f; bytes [bytes.length - 4] = EncodingTable [b1]; bytes [bytes.length - 3] = EncodingTable [b2]; bytes [bytes.length - 2] = (byte) '='; bytes [bytes.length - 1] = (byte) '='; romper; caso 2: d1 = data [data.length - 2] & 0xff; d2 = data [data.length - 1] & 0xff; b1 = (d1 >>> 2) y 0x3f; b2 = ((d1 << 4) | (d2 >>> 4)) y 0x3f; b3 = (d2 << 2) y 0x3f; bytes [bytes.length - 4] = EncodingTable [b1]; bytes [bytes.length - 3] = EncodingTable [b2]; bytes [bytes.length - 2] = EncodingTable [b3]; bytes [bytes.length - 1] = (byte) '='; romper; } bytes de retorno; } public static byte [] decode (byte [] data) {byte [] bytes; byte b1; byte b2; byte b3; byte b4; datos = DISCARDNONBASE64BYTES (datos); if (data [data.length - 2] == '=') {bytes = new byte [(((data.length / 4) - 1) * 3) + 1]; } else if (data [data.length - 1] == '=') {bytes = new byte [(((data.length / 4) - 1) * 3) + 2]; } else {bytes = new 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 [datos [i + 1]]; b3 = decodingtable [datos [i + 2]]; b4 = decodingtable [datos [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); } bytes de retorno; } public static byte [] decode (string data) {byte [] byte b1; byte b2; byte b3; byte b4; datos = DISCARDNONBASE64CHARS (datos); if (data.charat (data.length () - 2) == '=') {bytes = new 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 = new byte [((data.length ()) / 4) * 3)]; } for (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]); bytes de devolución; } byte estático privado [] Discardnonbase64bytes (byte [] data) {byte [] temp = new byte [data.length]; int byteScopied = 0; for (int i = 0; i <data.length; i ++) {if (isValidBase64byte (data [i])) {temp [bytescopied ++] = data [i]; }} byte [] newData = new Byte [bytescopied]; System.ArrayCopy (temp, 0, newdata, 0, bytescopied); regresar NewData; } cadena estática privada discoDDNonBase64Chars (string data) {StringBuffer sb = new StringBuffer (); int longitud = data.length (); for (int i = 0; i <longitud; i ++) {if (isValidbase64byte ((byte) (data.charat (i)))) {sb.append (data.charat (i)); }} return sb.ToString (); } booleano estático privado isvalidbase64byte (byte b) {if (b == '=') {return true; } else if ((b <0) || (b> = 128)) {return false; } else if (decodingtable [b] == -1) {return false; } return verdadero; } public static string code (string data, string charset) lanza la excepción {// byte [] resultado = (data.getBytes ("unicode")); if (data == null || data.length () == 0) return data; int offset = 0; // Después de gettingBytes ("unicode") se gira, se agregarán dos bytes "Fe" al byte frontal [] resultado = encode (data.getBytes (charset), offset); StringBuffer sb = new StringBuffer (result.length); para (int i = 0; i <result.length; i ++) sb.append ((char) resultado [i]); return sb.ToString (); } public static string decode (string data, string charset) lanza la excepción {if (data == null || data.length () == 0) return data; devolver nueva cadena (base64.Decode (datos), charset); } public static void main (string [] args) lanza la excepción {string data = "we"; String data1 = codde (datos, "unicode"); Cadena data2 = decode (data1, "unicode"); System.out.println (datos); System.out.println (data1); System.out.println (data2); }} Apéndice 2: Base64 Codificación en JavaScript
<html> <head> <title>base64 Encoding/Decoding</title> </head> <script type="text/javascript"><!-- var keyStr = "ABCDEFGHIJKLMNOP" + "QRSTUVWXYZabcdef" + "ghijklmnopqrstuv" + "wxyz0123456789+/" + "="; function codeD64 (input) {input = unicodetobytes (entrada); VAR Output = ""; var chr1, chr2, chr3 = ""; var enc1, enc2, enc3, enc4 = ""; var i = 0; do {chr1 = input [i ++]; chr2 = entrada [i ++]; chr3 = entrada [i ++]; enc1 = chr1 >> 2; enc2 = ((chr1 y 3) << 4) | (chr2 >> 4); enc3 = ((chr2 y 15) << 2) | (chr3 >> 6); enc4 = chr3 y 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); salida de retorno; } función decode64 (input) {var output = "" "; var chr1, chr2, chr3 = ""; var enc1, enc2, enc3, enc4 = ""; var i = 0; // Eliminar todos los caracteres que no son AZ, AZ, 0-9, +,/, o = var base64test =/[^a-Za-z0-9/ +/// =]/g; if (base64test.exec (input)) {alerta ("Hubo caracteres Base64 no válidos en el texto de entrada./n" + "Los caracteres Base64 válidos son AZ, AZ, 0-9, ' +', '/', y '='/n" + "Errores en decodificación"); } input = input.replace (/[^a-Za-z0-9/+//// =]/g, ""); salida = nuevo 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 y 15) << 4) | (enc3 >> 2); chr3 = ((enc3 y 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); return byTestOunicode (salida); } function unicodetobytes (s) {var resultado = new array (); if (s == nulo || s == "") Resultado de retorno; resultado.push (255); // Agregar "Fe" al resultado de la cabeza. Push (254); para (var i = 0; i <s.length; i ++) {var c = s.charcodeat (i) .ToString (16); if (c.length == 1) i = "000"+c; else 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; } function byTestOunicode (bs) {var result = ""; VAR offset = 0; if (bs.length> = 2 && bs [0] == 255 && bs [1] == 254) offset = 2; // Eliminar "Fe" para (var i = offset; i <bs.length; i+= 2) {var code = bs [i]+(bs [i+1] << 8); resultado+= String.FromCharCode (código); } resultado de retorno; } //-> </script> <body> <form de nombre = "base64form"> Escriba el mensaje que desea codificar en base64, o pegar <br> base64 codificado texto en el campo de texto, seleccione codificar o decodificar, <br> y haga clic en el botón! <BR> <TextArEnMe = "ThreText" Cols = "40" Rows = "6"> </TextAREA> <<MEXTIM> <BRIT TIPE = "BOTÓN" BOTÓN ". name = "encode" value = "code- a base64" onClick = "document.base64form.thetext.value = encode64 (document.base64form.thetext.value);"> <input type = "button" name = "decode =" decode from base64 "" onClick = "document.base64form.thetext.value = Decode64 (document.base64form.thetext.value);"> </form> </body> </html>Gracias por leer, espero que pueda ayudarte. ¡Gracias por su apoyo para este sitio!