扫一扫,微信登陆

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

搜索
查看: 667|回复: 0

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

[复制链接]

1万

主题

1万

帖子

5万

积分

论坛元老

Rank: 8Rank: 8

积分
56206
发表于 2022-9-11 21:05:01 | 显示全部楼层 |阅读模式
转载请注明文章出处:https://itlanyan.com/string-unicode-utf8-converter/& S6 U% X! z4 y- Z. K/ U
想知道某个字符串的UTF8编码,图方便打算使用在线工具。坑爹的是,号称“UTF8汉字互转”的网页几乎全是字符串和unicode码点互转,并不提供与UTF8编码互转功能。没搞懂unicode码点(code point)和UTF8编码的关系,还大言不惭的说UTF8编码,真让人无语。
5 @6 \7 w7 G6 u' i2 A5 l8 k) E0 F6 d* f3 y3 t6 E. j1 P: ?
: F: n7 c) L# m  t

/ Z0 b) J5 X4 j9 _) C+ Y0 g) v% ?6 {  d/ r# M/ q0 }

7 [1 r& M* O% E' g$ r字符、字节和字节序,unicode和UTF8编码,是理解字符编码重要的概念,详情可查看本人之前博文文件和字符编码。本文讨论unicode和UTF8之间的转换,先简要介绍两个概念:unicode是将字符与码点(code point,一个整数)一一对应的编码方案;码点通常用\uXXXX或者U+XXXX的方式表示,XXXX是码点的十六进制;UTF8是unicode的一个具体编码方案,规定字符存储的方式;UTF8编码字节数可变,不存在大小端问题,互联网通信中常采用此种编码方式。
- M3 X- X, U0 n( h回顾一下那成片的“汉字UTF8编码互转”网页所做的事情。以“中国”为例,两个汉字码点分别为20013和22269,十六进制表示4E2D 56FD,UTF8编码E4 B8 AD E5 9B BD。随手打开搜索结果中的http://www.ip138.com/utf8/,输入“中国”,点击“转换UTF-8”按钮,下方出现码点的十六进制编码4E2D 56FD(&#x可以理解为十六进制的前缀0x),并非UTF8编码。
2 m3 t1 s' ~4 L' GJavaScript的String对象有charCodeAt和codePointAt(兼容性不如charCodeAt)方法。根据这个函数,网页的转换工作可用如下代码实现:
+ A* I: h4 {7 P1 _function encode(str) {" J8 g! r+ [9 _3 T+ _+ @2 H
    var result = '';
3 l2 A( w: W. i- F* T- C    var len = str.length;; d( l3 B' s" O2 M( |+ @
    for (var i = 0; i 调用encode(“中国”)或者其他字符串,将得到每个字符对应码点的十六进制。但这不是字符串的UTF8编码!3 a1 J2 W1 T# A* [% S3 W
要拿到UTF8编码,需要在码点的基础上多走一步。先回顾unicode码点与UTF8的转换关系:
5 i. Y, ~2 E: T3 i, u0 `
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编码的函数:( o5 k+ h  p3 g2 A- k
// 获取字符串的utf8字节流
' V. i" N, f; R7 X8 |function getUTF8Bytes(str) {
/ Z4 y. W4 t+ ]  var bytes = [];  Q' u0 c# D- |: H  D
  var len = str.length;& ^/ r7 l9 e; \. U
  for (var i = 0; i = 0x10000 && code > 18) | 0xf0);                // 第一个字节8 _$ t1 b  b$ S* J
      bytes.push(((code >> 12) & 0x3f) | 0x80);6 O2 p' R. Y  q
      bytes.push(((code >> 6) & 0x3f) | 0x80);
. p$ P' S* D$ X! ?. r      bytes.push((code & 0x3f) | 0x80);
. c" D6 U2 v. h9 l& k' F    } else if (code >= 0x800 && code > 12) | 0xe0);$ ]. D" p5 |2 J! `2 Q1 d
      bytes.push(((code >> 6) & 0x3f) | 0x80);' [6 X9 j# I! M/ @$ y/ Z
      bytes.push((code & 0x3f) | 0x80);
% S' U# U: n) P1 g3 [    } else if (code >= 0x80 && code > 6) | 0xc0);& W: u, w' v+ A0 t7 q2 u( r8 p
       bytes.push((code & 0x3f) | 0x80);; S2 L. y0 l( _# q$ c) S
    } else {
& k5 T+ B. M8 [9 B; R( E% a+ y$ M      bytes.push(code)6 f$ E8 S" \, ~$ b
    }4 v( s' q$ o+ W# v; X( P, \
  }
: z; z% C1 P2 v: ~  return bytes;
! A/ V7 R/ ~0 I; N}$ T) d$ E0 }! O/ \
// 将字节流转换成16进制字符串
  N, M" e7 P6 Q7 [! m7 }function hexString(bytes) {! V2 I+ u5 z$ j! M8 k% M/ J. a
  var arr = bytes.map(function (code) {
) h8 Q0 ]9 @; @% H7 m    return (code).toString(16).toUpperCase();
, V& v7 Q0 J$ ]9 x6 S1 i5 S0 A3 a  });" Z% S7 q1 g6 X! b' e1 E- H
  return arr.join(' ');% B- V1 e  n; W7 K4 P2 y6 S& c! l( J
}
6 x7 I  L7 y# l# Cfunction utf8(str) {" T( M+ e! o. b: s: |
   return hexString(getUTF8Bytes(str));" N: m. k; i/ [2 M
}
1 P* y- w+ g; e3 t调用函数utf8,这才是JavaScript得到字符串的UTF8编码的正确姿势!从UTF8编码转换到字符串,做相反工作即可。+ {* _9 v' I+ y
AD:【国外VPS推荐】 Vultr全球16个数据中心,高速SSD硬盘,月付2.5$起,注册充10$送100$打赏赞(1)

本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

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