|
|
发表于 2022-9-11 21:05:01
|
查看: 1389 |
回复: 0
转载请注明文章出处:https://itlanyan.com/string-unicode-utf8-converter/: Q9 R( U" |% f5 ?1 Y$ F
想知道某个字符串的UTF8编码,图方便打算使用在线工具。坑爹的是,号称“UTF8汉字互转”的网页几乎全是字符串和unicode码点互转,并不提供与UTF8编码互转功能。没搞懂unicode码点(code point)和UTF8编码的关系,还大言不惭的说UTF8编码,真让人无语。
7 [: _, w: t5 O9 Q8 D7 w3 {
+ C! ^9 x8 O/ S ?% A- R$ @' p/ ~2 ^: b# G& u v+ l9 L( e# v* N
7 w$ M5 D. F7 Z- U7 F( L9 s
& ?- i& {# K& u( a1 d9 T3 c' r, D2 d3 \% @& ?
字符、字节和字节序,unicode和UTF8编码,是理解字符编码重要的概念,详情可查看本人之前博文文件和字符编码。本文讨论unicode和UTF8之间的转换,先简要介绍两个概念:unicode是将字符与码点(code point,一个整数)一一对应的编码方案;码点通常用\uXXXX或者U+XXXX的方式表示,XXXX是码点的十六进制;UTF8是unicode的一个具体编码方案,规定字符存储的方式;UTF8编码字节数可变,不存在大小端问题,互联网通信中常采用此种编码方式。# A( A B) A( z' ?* k1 ]
回顾一下那成片的“汉字UTF8编码互转”网页所做的事情。以“中国”为例,两个汉字码点分别为20013和22269,十六进制表示4E2D 56FD,UTF8编码E4 B8 AD E5 9B BD。随手打开搜索结果中的http://www.ip138.com/utf8/,输入“中国”,点击“转换UTF-8”按钮,下方出现码点的十六进制编码4E2D 56FD(&#x可以理解为十六进制的前缀0x),并非UTF8编码。/ H E3 g9 i1 C* s; r
JavaScript的String对象有charCodeAt和codePointAt(兼容性不如charCodeAt)方法。根据这个函数,网页的转换工作可用如下代码实现:
7 }+ g/ y, o5 f# a- h7 Yfunction encode(str) {+ O+ M7 g4 L& z+ }, N
var result = '';0 p r4 k5 _) U, [$ o! a7 g. Q6 y
var len = str.length;7 a$ x9 n: r2 V
for (var i = 0; i 调用encode(“中国”)或者其他字符串,将得到每个字符对应码点的十六进制。但这不是字符串的UTF8编码!1 s. w0 O* g' [; L
要拿到UTF8编码,需要在码点的基础上多走一步。先回顾unicode码点与UTF8的转换关系:, G$ u: g0 T2 {+ }; {$ z, i
| unicode码点(十六进制)[/td]UTF-8(二进制) | | 0000 0000-0000 007F | 0xxxxxxx | | 0000 0080-0000 07FF | 110xxxxx 10xxxxxx | | 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx | | 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 根据这个表,结合charCodeAt函数,可以写出字符串到UTF8编码的函数:
/ M! G2 f4 V% Q/ o* a// 获取字符串的utf8字节流$ v$ B e. [# y$ g% u: W7 W
function getUTF8Bytes(str) {3 O( t" y4 [8 L
var bytes = [];
- D5 l$ ^# m Y' H; D' ~ var len = str.length;1 {% c0 I( `& p( t: y
for (var i = 0; i = 0x10000 && code > 18) | 0xf0); // 第一个字节% l& X1 ?! w- e4 D" A1 h
bytes.push(((code >> 12) & 0x3f) | 0x80);+ f) \, H) g) ]: H! W: ^
bytes.push(((code >> 6) & 0x3f) | 0x80);
+ R4 G' ] Z) m3 r bytes.push((code & 0x3f) | 0x80);0 m; U! V4 {* Z8 R8 ?$ a+ }% E+ q) b2 [
} else if (code >= 0x800 && code > 12) | 0xe0);, W; v: y- z* }- \- g
bytes.push(((code >> 6) & 0x3f) | 0x80);
7 e" V" v( @8 D/ Q6 b4 [6 I+ Q bytes.push((code & 0x3f) | 0x80);8 {$ o( K) U% ~6 g2 O) |$ U# |3 ~
} else if (code >= 0x80 && code > 6) | 0xc0);/ A1 U+ W. B) [4 W8 z2 e
bytes.push((code & 0x3f) | 0x80);/ D% v* @7 b8 n- m$ Y4 L1 G
} else {" A, G; }& u/ o5 w- J
bytes.push(code)# H# b3 Q4 F" l m" K+ m
}
7 P$ g+ l- K+ c% T$ S, M6 l }. ]" t' O6 ~1 h# T! `0 a
return bytes;
4 D% z) m$ [( z" R( t6 b+ z! z) B}
4 V7 w) G' B" T" z" A" N" x// 将字节流转换成16进制字符串+ b: [; x: j* {; I+ ?
function hexString(bytes) {3 k* Z5 d9 X6 y3 s! d
var arr = bytes.map(function (code) {
6 F2 t! r7 ?& b+ | return (code).toString(16).toUpperCase();# d: Y* q! p, `! `% X5 q- ^0 f
});) q5 d% a) m ^3 C$ E/ W4 W
return arr.join(' ');" m5 {- ]6 Y3 a
}5 A4 I: V, {3 Y7 L e4 \
function utf8(str) {
, b8 d5 U- B& E) @ return hexString(getUTF8Bytes(str));
7 K Y7 f3 Y( v, i! C( S `( t/ k3 [}- U8 J. W$ I5 B/ Q- v& W
调用函数utf8,这才是JavaScript得到字符串的UTF8编码的正确姿势!从UTF8编码转换到字符串,做相反工作即可。
B. A' t9 n G( P3 Q; L( ]. [. F/ qAD:【国外VPS推荐】 Vultr全球16个数据中心,高速SSD硬盘,月付2.5$起,注册充10$送100$打赏赞(1) |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
|