扫一扫,微信登陆

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

搜索
查看: 335|回复: 0

字符串、unicode和UTF8编码之间的互相转换 - 青浦海洋数码电脑城

[复制链接]

1万

主题

1万

帖子

5万

积分

论坛元老

Rank: 8Rank: 8

积分
56206
发表于 2022-9-11 21:05:01 | 显示全部楼层 |阅读模式
转载请注明文章出处:https://itlanyan.com/string-unicode-utf8-converter/6 e' J% `8 n1 Q/ B7 h" W) O
想知道某个字符串的UTF8编码,图方便打算使用在线工具。坑爹的是,号称“UTF8汉字互转”的网页几乎全是字符串和unicode码点互转,并不提供与UTF8编码互转功能。没搞懂unicode码点(code point)和UTF8编码的关系,还大言不惭的说UTF8编码,真让人无语。
6 L% G+ i& Q2 B: S2 d, r& \3 @6 l9 _* `/ Q4 Z+ y) C

% x& t  b! _' r5 D$ `! d) ]( e3 ]( w* d( s! d7 f6 n

3 }7 a( l) h0 _1 M0 y6 A2 @- A
. q+ L: J* S3 C% m5 R' S* ~字符、字节和字节序,unicode和UTF8编码,是理解字符编码重要的概念,详情可查看本人之前博文文件和字符编码。本文讨论unicode和UTF8之间的转换,先简要介绍两个概念:unicode是将字符与码点(code point,一个整数)一一对应的编码方案;码点通常用\uXXXX或者U+XXXX的方式表示,XXXX是码点的十六进制;UTF8是unicode的一个具体编码方案,规定字符存储的方式;UTF8编码字节数可变,不存在大小端问题,互联网通信中常采用此种编码方式。
) B4 P* V1 K6 [* n6 D+ V, \9 {回顾一下那成片的“汉字UTF8编码互转”网页所做的事情。以“中国”为例,两个汉字码点分别为20013和22269,十六进制表示4E2D 56FD,UTF8编码E4 B8 AD E5 9B BD。随手打开搜索结果中的http://www.ip138.com/utf8/,输入“中国”,点击“转换UTF-8”按钮,下方出现码点的十六进制编码4E2D 56FD(&#x可以理解为十六进制的前缀0x),并非UTF8编码。
  Q& \4 p" F# N' D) D. b2 q9 rJavaScript的String对象有charCodeAt和codePointAt(兼容性不如charCodeAt)方法。根据这个函数,网页的转换工作可用如下代码实现:
4 ]% c* E  f; i8 ifunction encode(str) {+ {$ p9 ^3 m3 X! Y  J# ?+ D
    var result = '';
: Z; S+ X# T# ^  w8 b& z" Y; W    var len = str.length;
. P; p" I; O0 o; E    for (var i = 0; i 调用encode(“中国”)或者其他字符串,将得到每个字符对应码点的十六进制。但这不是字符串的UTF8编码!
, H, d  k& u; p; P7 x; W3 a要拿到UTF8编码,需要在码点的基础上多走一步。先回顾unicode码点与UTF8的转换关系:& I+ D* ?6 i% i
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编码的函数:
) q. J/ c+ x8 e% w) w2 `// 获取字符串的utf8字节流/ O" w: `& k) @: Q. q3 p$ M
function getUTF8Bytes(str) {6 g% G  @$ e+ C2 }% i! O! ]1 j7 k# d' `
  var bytes = [];
! z* C0 b  o: |$ [& r2 F8 P  var len = str.length;
4 p; {( O2 m! }; R  for (var i = 0; i = 0x10000 && code > 18) | 0xf0);                // 第一个字节. d5 J9 }' k" @  z& K- X
      bytes.push(((code >> 12) & 0x3f) | 0x80);7 L! F: F0 F2 d2 _
      bytes.push(((code >> 6) & 0x3f) | 0x80);
& _, C2 V( q3 s7 k2 C      bytes.push((code & 0x3f) | 0x80);/ w  m0 j' \% N0 s! b1 K% I
    } else if (code >= 0x800 && code > 12) | 0xe0);' n& a% ]) L- b2 S& k4 D
      bytes.push(((code >> 6) & 0x3f) | 0x80);
; q! R8 W# ^6 `6 k      bytes.push((code & 0x3f) | 0x80);! L5 T' l7 e& N/ h) L) w7 J
    } else if (code >= 0x80 && code > 6) | 0xc0);
, D1 K& s* x: K# [( f/ _4 |       bytes.push((code & 0x3f) | 0x80);5 |! z5 a' {3 [/ Y
    } else {
0 u$ W$ y7 o5 |- ]8 Y+ z      bytes.push(code)
' H! Q3 j$ l& v# i# S3 q    }/ A: c- l) X3 }% Q( Y9 U  X5 m1 D
  }5 K% W7 ]3 g; k9 ~* T
  return bytes;/ O$ |7 \0 k5 a4 E( o5 V
}
4 L( Q& T7 J- x& D0 Q// 将字节流转换成16进制字符串
" d: O1 \( |0 F$ y. M& }# q0 Mfunction hexString(bytes) {! n8 a, A0 W' ?4 N$ y7 i* q' J
  var arr = bytes.map(function (code) {
9 A% G- W" d/ G% {( A" f    return (code).toString(16).toUpperCase();# d5 b2 O2 T8 a/ g+ U
  });
7 f: O; e; b/ [+ d1 ]- b) g1 j  return arr.join(' ');; E. w5 w+ }: a  h
}
* y, ~( `) L1 a; Nfunction utf8(str) {; K8 |5 e) x6 M- Y# _: x% x) w
   return hexString(getUTF8Bytes(str));) F0 J) L  ^9 d$ ~" c
}* N8 @- Q( L5 Q- ^) V. C8 l
调用函数utf8,这才是JavaScript得到字符串的UTF8编码的正确姿势!从UTF8编码转换到字符串,做相反工作即可。# v# O- e( Y/ @! o2 d, _3 ?# I3 U
AD:【国外VPS推荐】 Vultr全球16个数据中心,高速SSD硬盘,月付2.5$起,注册充10$送100$打赏赞(1)

本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

Copyright © 2001-2013 Comsenz Inc.Powered by Discuz!X3.4( 沪ICP备18024137号 )
快速回复 返回顶部 返回列表