java和js用base64交互(中文乱码解决)

JS中UTF-8和UTF-16互转

1.由于服务端使用的Go,默认是使用UTF-8编码的,而JS默认是Unicode编码的(也就是UTF-16),所以为了字符串编码的一致性,将前端字符串数据编码转换为UTF-8之后再发送给服务端,服务端发送过来的字符串数据转换回UTF-16再使用。

PS:关于编码可参考《关于编码:Unicode/UTF-8/UTF-16/UTF-32

 

2.UTF-16转UTF-8

复制代码
            var utf16ToUtf8 = function (utf16Str) {
                var utf8Arr = [];
                var byteSize = 0;
                for (var i = 0; i < utf16Str.length; i++) {
                    //获取字符Unicode码值
                    var code = utf16Str.charCodeAt(i);

                    //如果码值是1个字节的范围,则直接写入
                    if (code >= 0x00 && code <= 0x7f) {
                        byteSize += 1;
                        utf8Arr.push(code);

                        //如果码值是2个字节以上的范围,则按规则进行填充补码转换
                    } else if (code >= 0x80 && code <= 0x7ff) {
                        byteSize += 2;
                        utf8Arr.push((192 | (31 & (code >> 6))));
                        utf8Arr.push((128 | (63 & code)))
                    } else if ((code >= 0x800 && code <= 0xd7ff)
                        || (code >= 0xe000 && code <= 0xffff)) {
                        byteSize += 3;
                        utf8Arr.push((224 | (15 & (code >> 12))));
                        utf8Arr.push((128 | (63 & (code >> 6))));
                        utf8Arr.push((128 | (63 & code)))
                    } else if(code >= 0x10000 && code <= 0x10ffff ){
                        byteSize += 4;
                        utf8Arr.push((240 | (7 & (code >> 18))));
                        utf8Arr.push((128 | (63 & (code >> 12))));
                        utf8Arr.push((128 | (63 & (code >> 6))));
                        utf8Arr.push((128 | (63 & code)))
                    }
                }

                return utf8Arr
            }
复制代码

 

 

3.UTF-8转UTF-16

复制代码
            var utf8ToUtf16 = function (utf8Arr) {
                var utf16Str = '';

                for (var i = 0; i < utf8Arr.length; i++) {
                    //每个字节都转换为2进制字符串进行判断
                    var one = utf8Arr[i].toString(2);

                    //正则表达式判断该字节是否符合>=2个1和1个0的情况
                    var v = one.match(/^1+?(?=0)/);

                    //多个字节编码
                    if (v && one.length == 8) {
                        //获取该编码是多少个字节长度
                        var bytesLength = v[0].length;

                        //首个字节中的数据,因为首字节有效数据长度为8位减去1个0位,再减去bytesLength位的剩余位数
                        var store = utf8Arr[i].toString(2).slice(7 - bytesLength);
                        for (var st = 1; st < bytesLength; st++) {
                            //后面剩余字节中的数据,因为后面字节都是10xxxxxxx,所以slice中的2指的是去除10
                            store += utf8Arr[st + i].toString(2).slice(2)
                        }

                        //转换为Unicode码值
                        utf16Str += String.fromCharCode(parseInt(store, 2));

                        //调整剩余字节数
                        i += bytesLength - 1
                    } else {
                        //单个字节编码,和Unicode码值一致,直接将该字节转换为UTF-16
                        utf16Str += String.fromCharCode(utf8Arr[i])
                    }
                }

                return utf16Str
            }










 

使用JS对中文字符串进行utf-8的Base64编码,使其与Java编码相同的办法

要进行编码的字符串:“select 用户名 from 用户”
使用JAVA进行编码,Java程序:
String sql = "select 用户名 from 用户";
String encodeStr = new String(Base64.encode(sql.getBytes("UTF-8"))); // 编码
System.out.println(encodeStr);

得到:c2VsZWN0IOeUqOaIt+WQjSBmcm9tIOeUqOaItw==


在Java中解码:sql = new String(Base64.decode(sql.getBytes()), "UTF-8");

Java代码中为什么要使用getBytes("UTF-8")呢?因为Windows和Linux环境下默认编码不同,要使你的程序在不同平台下得到相同编码,必然要指定编码

虽然Html和JS的编码都是utf-8,但JS从页面上得到的中文编码却是utf-16,所以直接对中文进行Base64编码将得到错误的结果,所以我们要先从utf-16转到utf-8再编码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
<!--
body{
  margin:0px;
  padding:0px;
}
body,td{
  font-size:9pt;
}
-->
</style>
<script type="text/javascript">
<!--
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
//将Ansi编码的字符串进行Base64编码
function encode64(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(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;
}
//将Base64编码字符串转换成Ansi编码的字符串
function decode64(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;


if (input.length % 4 != 0) {
return "";
}
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
return "";
}
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 = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output += String.fromCharCode(chr2);
}
if (enc4 != 64) {
output += String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}


function utf16to8(str) {
  var out, i, len, c;


  out = "";
  len = str.length;
  for(i = 0; i < len; i++) {
    c = str.charCodeAt(i);
    if ((c >= 0x0001) && (c <= 0x007F)) {
      out += str.charAt(i);
    } else if (c > 0x07FF) {
      out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
      out += String.fromCharCode(0x80 | ((c >>  6) & 0x3F));
      out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
    } else {
      out += String.fromCharCode(0xC0 | ((c >>  6) & 0x1F));
      out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
    }
  }
  return out;
}


function utf8to16(str) {
  var out, i, len, c;
  var char2, char3;


  out = "";
  len = str.length;
  i = 0;
  while(i < len) {
    c = str.charCodeAt(i++);
    switch(c >> 4) {
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += str.charAt(i-1);
        break;
      case 12: case 13:
        // 110x xxxx   10xx xxxx
        char2 = str.charCodeAt(i++);
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
        break;
      case 14:
        // 1110 xxxx  10xx xxxx  10xx xxxx
        char2 = str.charCodeAt(i++);
        char3 = str.charCodeAt(i++);
        out += String.fromCharCode(((c & 0x0F) << 12) |
        ((char2 & 0x3F) << 6) |
        ((char3 & 0x3F) << 0));
        break;
    }
  }
  return out;
}


// 测试代码 开始
var de = encode64(utf16to8("select 用户名 from 用户"));
document.writeln(de+"<br>");
var ee = utf8to16(decode64(de))
document.writeln(ee);
// 测试代码 结束


//-->
</script>
</head>
<body>
</body>
</html>

上面的代码都是从网上得来,拼凑后得到正确结果,在此感谢前辈们


转自:使用JS对中文字符串进行utf-8的Base64编码,使其与Java编码相同的办法
http://bbs.blueidea.com/thread-2914615-1-1.html





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值