请选择 进入手机版 | 继续访问电脑版

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

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

5万

积分

0

好友

1万

主题
发表于 2022-9-11 21:05:01 | 查看: 1317| 回复: 0
转载请注明文章出处:https://itlanyan.com/string-unicode-utf8-converter/8 N! B( R1 _8 }2 V
想知道某个字符串的UTF8编码,图方便打算使用在线工具。坑爹的是,号称“UTF8汉字互转”的网页几乎全是字符串和unicode码点互转,并不提供与UTF8编码互转功能。没搞懂unicode码点(code point)和UTF8编码的关系,还大言不惭的说UTF8编码,真让人无语。
4 B8 b- h1 X; W" `. W" j; V! t3 j: z& P

. |1 A4 u# H# a# u# |6 s8 b, ]9 f+ N& V; i

' K! ?- {0 Y, u! l5 m. G9 B7 a( M6 t$ B- y4 R
字符、字节和字节序,unicode和UTF8编码,是理解字符编码重要的概念,详情可查看本人之前博文文件和字符编码。本文讨论unicode和UTF8之间的转换,先简要介绍两个概念:unicode是将字符与码点(code point,一个整数)一一对应的编码方案;码点通常用\uXXXX或者U+XXXX的方式表示,XXXX是码点的十六进制;UTF8是unicode的一个具体编码方案,规定字符存储的方式;UTF8编码字节数可变,不存在大小端问题,互联网通信中常采用此种编码方式。
8 E" w! z5 I, U回顾一下那成片的“汉字UTF8编码互转”网页所做的事情。以“中国”为例,两个汉字码点分别为20013和22269,十六进制表示4E2D 56FD,UTF8编码E4 B8 AD E5 9B BD。随手打开搜索结果中的http://www.ip138.com/utf8/,输入“中国”,点击“转换UTF-8”按钮,下方出现码点的十六进制编码4E2D 56FD(&#x可以理解为十六进制的前缀0x),并非UTF8编码。
" ^; [4 e8 f0 {' U: {JavaScript的String对象有charCodeAt和codePointAt(兼容性不如charCodeAt)方法。根据这个函数,网页的转换工作可用如下代码实现:" n+ I5 R  c6 ]
function encode(str) {5 W( J) b7 r0 G5 M2 n: h* y; B4 ~
    var result = '';
! c' a) j) ?# y# c/ k; R: @2 ]    var len = str.length;+ }! E+ W( U' I
    for (var i = 0; i 调用encode(“中国”)或者其他字符串,将得到每个字符对应码点的十六进制。但这不是字符串的UTF8编码!, ?! d# h% s2 n2 J9 y* e9 M8 Y
要拿到UTF8编码,需要在码点的基础上多走一步。先回顾unicode码点与UTF8的转换关系:! X& e! A5 U, E- [3 n; Y4 Q
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& A4 Q, F4 l  k/ U- W9 v// 获取字符串的utf8字节流
7 J0 `3 Y& _( X) ofunction getUTF8Bytes(str) {& r! r' D" w2 o: z0 o& P' J. C
  var bytes = [];
2 {3 y1 D# Q0 W/ I* P& l  var len = str.length;) q& ?: p# s* _( B' l
  for (var i = 0; i = 0x10000 && code > 18) | 0xf0);                // 第一个字节" X- ^$ j) r; v0 @" V* T
      bytes.push(((code >> 12) & 0x3f) | 0x80);- ]+ e3 k7 C3 K% h/ ^" o
      bytes.push(((code >> 6) & 0x3f) | 0x80);
+ W$ {# J2 G, G: o8 m. y3 ~5 ?7 F      bytes.push((code & 0x3f) | 0x80);( A3 r) A& R( ^5 N' V" a
    } else if (code >= 0x800 && code > 12) | 0xe0);
( b- b& E* B: h9 `8 f% [      bytes.push(((code >> 6) & 0x3f) | 0x80);
" F9 I; c& O) U% ?7 m" @- o      bytes.push((code & 0x3f) | 0x80);
! x2 B  n  P0 x# p4 J$ r    } else if (code >= 0x80 && code > 6) | 0xc0);
- ?6 R$ f9 c: k, }& f( j7 `' a- p       bytes.push((code & 0x3f) | 0x80);6 c. X2 y% T1 j0 [  |
    } else {2 Z  C0 l/ U( v# m+ y
      bytes.push(code)) G; B7 b+ m' r" R/ ]
    }7 o! T& t5 l) L
  }
2 U$ W+ |$ }. d6 P2 g. k  return bytes;0 y5 E$ I, ^. X8 P* n8 E3 K. r
}
* [+ a* R+ A' r1 C. K// 将字节流转换成16进制字符串
% Y& U$ v6 |" v2 z) ~# gfunction hexString(bytes) {
" K) [7 C/ H) v& c) s* O  var arr = bytes.map(function (code) {1 J1 N) t: ?4 |* U
    return (code).toString(16).toUpperCase();
# s6 e3 x  ?5 m6 m9 b) e  });
" g+ m! k+ w4 I0 O* T% `! ^$ _  return arr.join(' ');
( j6 ^1 x6 R2 T$ n/ k; R}
& _) p6 N0 D' W. P1 Pfunction utf8(str) {
0 Q1 ]* ]7 B8 n4 O  c  }   return hexString(getUTF8Bytes(str));1 ~7 ?7 a3 _- T  C/ x4 _4 s" @
}
: t9 z  L6 ]. p调用函数utf8,这才是JavaScript得到字符串的UTF8编码的正确姿势!从UTF8编码转换到字符串,做相反工作即可。9 @# l  |9 d0 X! w% Q# M
AD:【国外VPS推荐】 Vultr全球16个数据中心,高速SSD硬盘,月付2.5$起,注册充10$送100$打赏赞(1)

本帖子中包含更多资源

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

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

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

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

GMT+8, 2026-8-16 06:54 , Processed in 0.073842 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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