青浦修电脑 青浦笔记本维修 青浦手机维修 青浦电器维修

找回密码
立即注册
搜索
热搜: 活动 交友 discuz
发新帖

5万

积分

0

好友

1万

主题
发表于 2022-9-11 21:05:01 | 查看: 1393| 回复: 0
转载请注明文章出处:https://itlanyan.com/string-unicode-utf8-converter/
: L6 c+ u( d! r8 ]/ _. H
想知道某个字符串的UTF8编码,图方便打算使用在线工具。坑爹的是,号称“UTF8汉字互转”的网页几乎全是字符串和unicode码点互转,并不提供与UTF8编码互转功能。没搞懂unicode码点(code point)和UTF8编码的关系,还大言不惭的说UTF8编码,真让人无语。
: f0 |$ j2 m3 B/ s: X0 s
- S& J( D  [! w% R5 Z, K2 @  U- b3 L+ I% _; ~0 t+ z; e8 L  i, R

) ]/ k2 a- a9 z- \. o7 F
2 f! ^* r" t/ b' S0 w/ ?4 N. d
' ^1 W0 p* y1 {$ R" y9 E字符、字节和字节序,unicode和UTF8编码,是理解字符编码重要的概念,详情可查看本人之前博文文件和字符编码。本文讨论unicode和UTF8之间的转换,先简要介绍两个概念:unicode是将字符与码点(code point,一个整数)一一对应的编码方案;码点通常用\uXXXX或者U+XXXX的方式表示,XXXX是码点的十六进制;UTF8是unicode的一个具体编码方案,规定字符存储的方式;UTF8编码字节数可变,不存在大小端问题,互联网通信中常采用此种编码方式。& ~$ }: _1 C: \- L% c* D' |
回顾一下那成片的“汉字UTF8编码互转”网页所做的事情。以“中国”为例,两个汉字码点分别为20013和22269,十六进制表示4E2D 56FD,UTF8编码E4 B8 AD E5 9B BD。随手打开搜索结果中的http://www.ip138.com/utf8/,输入“中国”,点击“转换UTF-8”按钮,下方出现码点的十六进制编码4E2D 56FD(&#x可以理解为十六进制的前缀0x),并非UTF8编码。/ c* C1 ?5 A  X5 i) n
JavaScript的String对象有charCodeAt和codePointAt(兼容性不如charCodeAt)方法。根据这个函数,网页的转换工作可用如下代码实现:
3 _' c8 `0 k; M  ]3 L* j  g7 ?function encode(str) {
7 H- z6 ~8 F; {0 k$ t, a    var result = '';" O5 Z/ [; \/ |) p1 S2 b- ~( K4 `
    var len = str.length;
0 O( i. R% I# L- O2 j9 v0 W/ f' h    for (var i = 0; i 调用encode(“中国”)或者其他字符串,将得到每个字符对应码点的十六进制。但这不是字符串的UTF8编码!
# x+ k3 D0 ]8 c* C' W; K8 U要拿到UTF8编码,需要在码点的基础上多走一步。先回顾unicode码点与UTF8的转换关系:
& g4 {+ d: H! v$ h# r. h3 [2 ]
unicode码点(十六进制)[/td]UTF-8(二进制)
0000 0000-0000 007F0xxxxxxx
0000 0080-0000 07FF110xxxxx 10xxxxxx
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
根据这个表,结合charCodeAt函数,可以写出字符串到UTF8编码的函数:. k0 [8 ^' }5 S  a  G0 {1 v9 T/ A
// 获取字符串的utf8字节流
* c( `6 a9 v- E3 b; ?2 n1 w! I; M* A4 bfunction getUTF8Bytes(str) {0 L5 z+ ?4 _7 L% ~6 u
  var bytes = [];& c: Y- a# @7 j* {4 a6 J
  var len = str.length;
! k& ?: h7 i, E' Y; X  for (var i = 0; i = 0x10000 && code > 18) | 0xf0);                // 第一个字节
1 m% j5 `9 ^4 w1 r4 @- L      bytes.push(((code >> 12) & 0x3f) | 0x80);
- J) K' B" d0 R& i7 ]      bytes.push(((code >> 6) & 0x3f) | 0x80);' J5 [9 ^& D& L: B' I4 T  j; F6 g
      bytes.push((code & 0x3f) | 0x80);
& t0 z' B1 k8 J; h- ]4 m3 E    } else if (code >= 0x800 && code > 12) | 0xe0);
5 G& H! y6 a0 ~- b6 k" P0 u      bytes.push(((code >> 6) & 0x3f) | 0x80);
+ O# E' L* V6 }) A      bytes.push((code & 0x3f) | 0x80);2 V# w/ a/ F$ j6 U' P9 q
    } else if (code >= 0x80 && code > 6) | 0xc0);5 Q. v1 k5 W$ L9 o! V
       bytes.push((code & 0x3f) | 0x80);4 X- W2 J" s, a* ~* V
    } else {( j$ v9 K8 P& l3 [
      bytes.push(code)
& W2 w# c7 P$ S4 B: S8 c! m    }/ h( a  K. [" J6 H9 i
  }
3 b+ n1 Q" I* A! K  return bytes;/ n: _0 D! g' ?' d6 g$ k( d9 D6 l
}
! D2 b& [. s5 ?1 R// 将字节流转换成16进制字符串( ^0 E4 y' T* Q* A. t5 [* p) V9 J
function hexString(bytes) {
9 U; q; W2 Z8 v9 _/ h  var arr = bytes.map(function (code) {5 }4 z# C, Z2 z8 a
    return (code).toString(16).toUpperCase();
1 L0 q% I4 K* R. z  });0 s8 F! v+ I) G5 y3 D" o) P/ Z
  return arr.join(' ');5 a% ^  U' Y8 u3 z6 T
}
& @) O' S, A3 E- cfunction utf8(str) {
4 y( G- T* K2 h! e   return hexString(getUTF8Bytes(str));
8 B6 u5 `( ]4 D5 U5 {}+ X% l3 K3 t, d! C! @: i5 P
调用函数utf8,这才是JavaScript得到字符串的UTF8编码的正确姿势!从UTF8编码转换到字符串,做相反工作即可。
* |3 Q" Y& m5 T* t0 j& F& RAD:【国外VPS推荐】 Vultr全球16个数据中心,高速SSD硬盘,月付2.5$起,注册充10$送100$打赏赞(1)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

收藏回复 显示全部楼层 道具 举报

您需要登录后才可以回帖 登录 | 立即注册

QQ|Archiver|手机版|小黑屋|青浦海洋数码电脑城 ( 沪ICP备18024137号 )

GMT+8, 2026-9-24 16:58 , Processed in 0.064157 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表