一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

解决svn list 显示中文乱码问题的方法

时间:2016-06-18 编辑:简简单单 来源:一聚教程网

一、背景

我们使用svn pre-commit hook做了一个svn锁定的功能,对于在上线前的svn提交进行控制,防止开发及策划胡乱提交,导致线上bug。这个平台有一个web界面功能,可以争对性给某些人开通一次提交权限,并记录他这一次的提交文件和log,乱码就出现了,web界面上显示的中文均乱码,包括log和提交文件名称

乱码的格式是:/design/X_?229?175?188?229?133?165?230?149?176?230?141?174/04_?233?129?147?229?133?183?230?149?176?230?141?174?232?161?168/?229?149?134?229?186?151?230?149?176?230?141?174?232?161?168.xls 这样的;

例如web上乱码为:

14370127901362.png


对应实际的中文汉字为:

14370128636098.png


二、原因

字符编码的问题,大家都知道,主要是ascii编码和unicode、utf-8之间的转换。关于字符编码,可以看阮一峰老师的文章,解析简单透彻:http://www.ruanyifeng.com/blog ... .html

上述乱码基本是?229格式的,其中的?应该是svn自己加的分隔符,后面的三位数字为ascii编码,我们可以通过ascii转字符的函数将它转换成字符,将上述所有ascii字符拼接到一起即可形成unicode编码,然后再转utf-8,即可得到UrlEncode之后的中文汉字,然后再UrlDecode即可;

三、解决

知道上述原理之后,我采用js解决,这样不用修改后端代码,服务器也不用reload,调试也会方便一些;如果你才用其他语言,比如python、java、php等去解析乱码。可以找对应的函数替换即可。

3.1 urldecode和urlencode

比如:http://www.111com.net  /%E5%88%86%E5%B8%83%E5%BC%8F.html 这个链接里面的%E5%88%86%E5%B8%83%E5%BC%8F就是UrlEncode之后的中文,使用UrlDecode即可得到汉字“分布式”。关于这部分,网络博客很多,随便找;

Javascript方法如下:
function UrlDecode(zipStr){ 
    var uzipStr=""; 
    for(var i=0;i         var chr = zipStr.charAt(i); 
        if(chr == "+"){ 
            uzipStr+=" "; 
        }else if(chr=="%"){ 
            var asc = zipStr.substring(i+1,i+3); 
            if(parseInt("0x"+asc)>0x7f){ 
                uzipStr+=decodeURI("%"+asc.toString()+zipStr.substring(i+3,i+9).toString()); 
                i+=8; 
            }else{ 
                uzipStr+=AsciiToString(parseInt("0x"+asc)); 
                i+=2; 
            } 
        }else{ 
            uzipStr+= chr; 
        } 
    }
    return uzipStr; 
}
3.2 unicode转utf-8:EncodeUtf8

这部分代码网上找的,可能有bug,我用上没有什么问题,其他语言应该有更简单的方法:
function EncodeUtf8(s1) {
    var s = escape(s1);
    var sa = s.split("%");
    var retV = "";
    if (sa[0] != "") {
        retV = sa[0];
    }
    for (var i = 1; i < sa.length; i++) {
        if (sa[i].substring(0, 1) == "u") {
            retV += Hex2Utf8(Str2Hex(sa[i].substring(1, 5)));
        } else retV += "%" + sa[i];
    }
    return retV;
}
function Str2Hex(s) {
    var c = "";
    var n;
    var ss = "0123456789ABCDEF";
    var digS = "";
    for (var i = 0; i < s.length; i++) {
        c = s.charAt(i);
        n = ss.indexOf(c);
        digS += Dec2Dig(eval(n));
    }
    //return value;
    return digS;
}
function Dec2Dig(n1) {
    var s = "";
    var n2 = 0;
    for (var i = 0; i < 4; i++) {
        n2 = Math.pow(2, 3 - i);
        if (n1 >= n2) {
            s += '1';
            n1 = n1 - n2;
        } else
            s += '0';
    }
    return s;
}
function Dig2Dec(s) {
    var retV = 0;
    if (s.length == 4) {
        for (var i = 0; i < 4; i++) {
            retV += eval(s.charAt(i)) * Math.pow(2, 3 - i);
        }
        return retV;
    }
    return -1;
}
function Hex2Utf8(s) {
    var retS = "";
    var tempS = "";
    var ss = "";
    if (s.length == 16) {
        tempS = "1110" + s.substring(0, 4);
        tempS += "10" + s.substring(4, 10);
        tempS += "10" + s.substring(10, 16);
        var sss = "0123456789ABCDEF";
        for (var i = 0; i < 3; i++) {
            retS += "%";
            ss = tempS.substring(i * 8, (eval(i) + 1) * 8);
            retS += sss.charAt(Dig2Dec(ss.substring(0, 4)));
            retS += sss.charAt(Dig2Dec(ss.substring(4, 8)));
        }
        return retS;
    }
    return "";
}
3.3 解析SVN乱码

解析SVN格式乱码,获得每个字符的ascii,然后拼接unicode,然后转utf8,然后再UrlDecode,成功解析出汉字;
function svn_ascii_to_utf8(ori) {
  s = ori.split('?');
  //三个才是一个汉字,至少要有一个汉字
  if (s.length < 3) {
    return ori;
  }
  var ascii = '';
  for(i in s) {
    x = s[i];
    if (x.length == 3) {
      ascii += String.fromCharCode(x);
      //console.log(ascii);
    }
    else if (x.length > 3) {
      ascii += String.fromCharCode(x.substr(0, 3));
      ascii += x.substr(3);
    }
    else {
      //do nothing
    }
  }
  return UrlDecode(EncodeUtf8(ascii));
}
然后再web页面显示的时候,将相应的乱码,调用s = svn_ascii_to_utf8(s)即可,有乱码转乱码,无乱码保持不变;

热门栏目