GIT乱码原因解决方法及解释

现象:
GIT 中的中文名: 中文.txt 会转码为:

 "src/components/\344\270\255\346\226\207.txt"

解决方法:

$ git config  core.quotepath false

原因:

“中”是按UTF8编码存在磁盘上,真实的2进制编码为:

11 100 100 10 111 000 10 101 101

8进制为 (这里要留意:是按每个byte,8bit最左补0,9bit来转换;而不是简单合到一起转换):

011 100 100 | 010 111 000 | 010 101 101
3 4 4 | 2 7 0 | 2 5 5

16进制编码为

e4 b8 ad

参考代码

16进制的获取方法很多:

  • python: print('中'.encode('utf8'))b16=[hex(b) for b in '中'.encode('utf8')]
  • ES6: encodeURIComponent("中");
  • Java: System.out.println(URLEncoder.encode("中","utf8"))
  • Mysql: select '中', HEX('中'), char(0xE4B8AD using utf8mb4)

8进制的获取方法:

  • python: b8=[oct(b) for b in '中'.encode('utf8')];

  • ES6: let [b10,b8,b2]=[[],[],[]];new TextEncoder().encode("中").forEach(b=>{b10.push(b); b8.push(b.toString(8)); b2.push(b.toString(2));});console.log(b10,b8,b2);

  • Java Bytes.asList("中".getBytes("utf8")).stream().forEach(_b->System.out.println(Integer.toOctalString(_b & 0xFF) + " "));

  • MySQL select OCT(0xE4), OCT(0xB8), OCT(0xAD)

2进制的获取方法:

  • python: b2=[bin(b) for b in '中'.encode('utf8')]

  • ES6: let [b10,b8,b2]=[[],[],[]];new TextEncoder().encode("中").forEach(b=>{b10.push(b); b8.push(b.toString(8)); b2.push(b.toString(2));});console.log(b10,b8,b2);

  • Java Bytes.asList("中".getBytes("utf8")).stream().forEach(_b->System.out.println(Integer.toBinaryString(_b & 0xFF) + " "));

  • Mysql select BIN(0xE4), BIN(0xE4), BIN(0xAD)

Git源代码参考

源文件片段 quote.c:

if (cq_lookup[ch] >= ' ') {
	EMIT(cq_lookup[ch]);
} else {
	EMIT(((ch >> 6) & 03) + '0');
	EMIT(((ch >> 3) & 07) + '0');
	EMIT(((ch >> 0) & 07) + '0');
}

解释:
#11 100 100 转8进制 344
#11 100 100 (ch >> 6) & 03 >>> 11 & 11 >>> 11 >>> 3
#11 100 100 (ch >> 3) & 07 >>> 11100 & 111 >>> 100 >>> 4
#11 100 100 (ch >> 0) & 07 >>> 11100100 & 111 >>> 100 >>> 4

补充:16|8|2进制编码转中文:

  • python:
print('------------------------------decode---------------------------------')
print(bytes([int(b,2) for b in b2]).decode("utf-8"))
print(bytes([int(b,8) for b in b8]).decode("utf-8"))
print(bytes([int(b,10) for b in b10]).decode("utf-8"))
print(bytes([int(b,16) for b in b16]).decode("utf-8"))
  • ES6:
new TextDecoder().decode(Uint8Array.from(b10))
new TextDecoder().decode(Uint8Array.from(b8.map(b=>{return parseInt(''+b,8)})))
new TextDecoder().decode(Uint8Array.from(b2.map(b=>{return parseInt(''+b,2)})))
  • Java
  //bytes to char
    System.out.println(newString(new int[]{228,184,173},10, "utf8"));
    System.out.println(newString(new int[]{344,270,255},8, "utf8"));
    System.out.println(newString(new int[]{11100100,10111000,10101101},2, "utf8"));
    
    public static String newString(int[] i, int radix,String encoding) throws UnsupportedEncodingException {
	    byte[] b2= new byte[i.length];
	    for (int j=0;j<i.length;j++) {
	        int i1 = Integer.parseInt("" + i[j], radix);
	        b2[j]=(byte) (i1 & 0xFF);
	    }
	    String utf8 = new String(b2, encoding);
	    return utf8;
	}
  • Mysql select '中', char(0xE4B8AD using utf8mb4)
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值