Java and JavaScript really common Base64 coding detailed _java

Source: Internet
Author: User
Tags base64 modulus java web stringbuffer


Java and JavaScript Base64 encoding



When developing Java Web applications, it is possible to use Java for BASE64 encoding on the server side, while the client can decode it with JavaScript. This requires consistency of Base64 coding mechanisms on both sides.



Using BASE64 encoding, you may encounter a variety of strange situations, and even suspect that the code has bugs. But that's not really the case. Base64 in theory is not a string but a byte array. Its principle is to reduce the ASCII code 255 characters to be represented in 64. Specifically, the original three bytes in four bytes, the length of the code after a certain increase.



1 It is best to encode one time, to avoid piecewise coding, and indeed to segment the encoding, each byte number should be a multiple of 3.



Long word throttling, if you want to read edge encoding, each paragraph must be a multiple of 3, otherwise it may be in the restoration of chaos. The average person prefers to define an array with a 2 exponentiation, such as byte[1024], because it is not a multiple of 3, and may have an error when restoring. The correct examples are:



Byte[] bs=new byte[3*100] ... inputstream.read (BS) ... encode (BS) ....



For strings, it is generally encoded all at once to avoid error in fragment encoding.



Of course, if you fragment coding, restore time is also a period of restore, that is no problem.



2) To ensure that the string restore in accordance with the original code restore.



Because it operates a byte array, the result is not the same for GBK encoded Chinese characters and UTF-8 encoded characters after BASE64 encoding. For example, "we" the two words if it is GBK code, turn into Base64 is ztldxw==, if it is UTF-8 code, turn Base64 after 5oir5lus.



That is "we" = = "GetBytes (" GBK ") ==> Base64



So what is the code conversion for Java side, what code to restore in JavaScript. To make sure that Java and JavaScript are common, we use Unicode encoding (JavaScript to UTF-8, GBK inconvenient, so we use its own Unicode encoding), as follows:



Server side:



1 Use GetBytes ("Unicode") to convert to a Unicode byte array.



2) encoded into a Base64 string



3) Transfer to client



Client:






1) Base64 decoding into byte array



2) Restore by Unicode



The code is as follows (see attachment for related functions):



Base64.encode (data, "Unicode"); Java-side encoding



DECODE64 (data); JavaScript decoding



Annex I: Java BASE64 encoding


package 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) '/' 
    }; 
  private static final byte[] decodingTable; 
  static { 
    decodingTable = new byte[128]; 
    for (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[] encode(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 = data[i + 1] & 0xff; 
      a3 = data[i + 2] & 0xff; 
      bytes[j] = encodingTable[(a1 >>> 2) & 0x3f]; 
      bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]; 
      bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]; 
      bytes[j + 3] = encodingTable[a3 & 0x3f]; 
    } 
    int b1; 
    int b2; 
    int b3; 
    int d1; 
    int d2; 
    switch (modulus) { 
    case 0: /* nothing left to do */ 
      break; 
    case 1: 
      d1 = data[data.length - 1] & 0xff; 
      b1 = (d1 >>> 2) & 0x3f; 
      b2 = (d1 << 4) & 0x3f; 
      bytes[bytes.length - 4] = encodingTable[b1]; 
      bytes[bytes.length - 3] = encodingTable[b2]; 
      bytes[bytes.length - 2] = (byte) '='; 
      bytes[bytes.length - 1] = (byte) '='; 
      break; 
    case 2: 
      d1 = data[data.length - 2] & 0xff; 
      d2 = data[data.length - 1] & 0xff; 
      b1 = (d1 >>> 2) & 0x3f; 
      b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f; 
      b3 = (d2 << 2) & 0x3f; 
      bytes[bytes.length - 4] = encodingTable[b1]; 
      bytes[bytes.length - 3] = encodingTable[b2]; 
      bytes[bytes.length - 2] = encodingTable[b3]; 
      bytes[bytes.length - 1] = (byte) '='; 
      break; 
    } 
    return bytes; 
  } 
  public static byte[] decode(byte[] data) { 
    byte[] bytes; 
    byte b1; 
    byte b2; 
    byte b3; 
    byte b4; 
    data = discardNonBase64Bytes(data); 
    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)]; 
    } 
    for (int i = 0, j = 0; i < (data.length - 4); i += 4, j += 3) { 
      b1 = decodingTable[data[i]]; 
      b2 = decodingTable[data[i + 1]]; 
      b3 = decodingTable[data[i + 2]]; 
      b4 = decodingTable[data[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); 
    } 
    return bytes; 
  } 
  public static byte[] decode(String data) { 
    byte[] bytes; 
    byte b1; 
    byte b2; 
    byte b3; 
    byte b4; 
    data = discardNonBase64Chars(data); 
    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); 
    } 
    for(int i=0;i<bytes.length;i++) System.out.println(","+bytes[i]); 
    return bytes; 
  } 
  private static byte[] 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); 
    return newData; 
  } 
  private static String discardNonBase64Chars(String data) { 
    StringBuffer sb = new StringBuffer(); 
    int length = data.length(); 
    for (int i = 0; i < length; i++) { 
      if (isValidBase64Byte((byte) (data.charAt(i)))) { 
        sb.append(data.charAt(i)); 
      } 
    } 
    return sb.toString(); 
  } 
  private static boolean isValidBase64Byte(byte b) { 
    if (b == '=') { 
      return true; 
    } else if ((b < 0) || (b >= 128)) { 
      return false; 
    } else if (decodingTable[b] == -1) { 
      return false; 
    } 
    return true; 
  } 
  public static String encode(String data,String charset)throws Exception 
  { 
    // byte[] result = (data.getBytes("Unicode")); 
     if(data==null || data.length()==0) return data; 
     int offset=0; 
     // getBytes("unicode")转完后会在前头加上两字节”FE“ 
     byte[] result=encode (data.getBytes(charset),offset); 
     StringBuffer sb=new StringBuffer(result.length); 
     for (int i=0;i<result.length;i++)  sb.append((char)result[i]); 
     return sb.toString(); 
  } 
  public static String decode(String data,String charset)throws Exception 
  { 
    if(data==null || data.length()==0) return data; 
    return new String(Base64.decode(data),charset); 
  } 
  public static void main(String[] args) throws Exception { 
    String data = "我们"; 
    String data1=encode(data,"Unicode"); 
    String data2=decode(data1,"Unicode"); 
    System.out.println(data); 
    System.out.println(data1); 
    System.out.println(data2); 
  } 
}


with two: Base64 encoding

in JavaScript


<html> 
<head> 
<title>base64 Encoding/Decoding</title> 
</head> 
<script type="text/javascript"><!-- 
var keyStr = "ABCDEFGHIJKLMNOP" + 
       "QRSTUVWXYZabcdef" + 
       "ghijklmnopqrstuv" + 
       "wxyz0123456789+/" + 
       "=";

function encode64(input) { 
  input = unicodetoBytes(input); 
  var output = ""; 
  var chr1, chr2, chr3 = ""; 
  var enc1, enc2, enc3, enc4 = ""; 
  var i = 0;

  do { 
   chr1 = input[i++]; 
   chr2 = input[i++]; 
   chr3 = input[i++];

   enc1 = chr1 >> 2; 
   enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 
   enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 
   enc4 = chr3 & 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);

  return output; 
}

function decode64(input) { 
  var output = ""; 
  var chr1, chr2, chr3 = ""; 
  var enc1, enc2, enc3, enc4 = ""; 
  var i = 0;

  // remove all characters that are not A-Z, a-z, 0-9, +, /, or = 
  var base64test = /[^A-Za-z0-9/+///=]/g; 
  if (base64test.exec(input)) { 
   alert("There were invalid base64 characters in the input text./n" + 
      "Valid base64 characters are A-Z, a-z, 0-9, '+', '/', and '='/n" + 
      "Expect errors in decoding."); 
  } 
  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 & 15) << 4) | (enc3 >> 2); 
   chr3 = ((enc3 & 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(output); 
}

 function unicodetoBytes(s) 
  { 
   var result=new Array(); 
   if(s==null || s=="") return result; 
   result.push(255); // add "FE" to head 
   result.push(254); 
   for(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); 
    result.push( var1); 
    result.push(var2) ; 
   } 
   return result; 
  }

  function bytesToUnicode(bs) 
  { 
   var result=""; 
   var offset=0; 
   if(bs.length>=2 && bs[0]==255 && bs[1]==254) offset=2; // delete "FE" 
   for(var i=offset;i<bs.length;i+=2) 
   { 
      var code=bs[i]+(bs[i+1]<<8); 
      result+=String.fromCharCode(code); 
   } 
   return result; 
  } 
//--> 
</script> 
<body> 
<form name="base64Form"> 
  Type in the message you want to encode in base64, or paste<br> 
  base64 encoded text into the text field, select Encode or Decode, <br> 
  and click the button!<br>

  <textarea name="theText" cols="40" rows="6"></textarea><br>

  <input type="button" name="encode" value="Encode to base64" 
   onClick="document.base64Form.theText.value=encode64(document.base64Form.theText.value);"> 
  <input type="button" name="decode" value="Decode from base64" 
   onClick="document.base64Form.theText.value=decode64(document.base64Form.theText.value);"> 
</form> 
</body> 
</html>


Thank you for reading, I hope to help you, thank you for your support for this site!


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.