首先要了解下UTF-8同unicode的关系
UTF-8编码为变长编码。最小编码单位(code unit
)为一个字节。一个字节的前1-3个bit为描述性部分,后面为实际序号部分。
- 如果一个字节的第一位为0,那么代表当前字符为单字节字符,占用一个字节的空间。0之后的所有部分(7个bit)代表在Unicode中的序号。
- 如果一个字节以110开头,那么代表当前字符为双字节字符,占用2个字节的空间。110之后的所有部分(5个bit)加上后一个字节的除10外的部分(6个bit)代表在Unicode中的序号。且第二个字节以10开头
- 如果一个字节以1110开头,那么代表当前字符为三字节字符,占用3个字节的空间。110之后的所有部分(5个bit)加上后两个字节的除10外的部分(12个bit)代表在Unicode中的序号。且第二、第三个字节以10开头
- 如果一个字节以10开头,那么代表当前字节为多字节字符的第二个字节。10之后的所有部分(6个bit)和之前的部分一同组成在Unicode中的序号。
具体每个字节的特征可见下表,其中x
代表序号部分,把各个字节中的所有x
部分拼接在一起就组成了在Unicode字库中的序号
0xxx xxxx | ||
110x xxxx | 10xx xxxx | |
1110 xxxx | 10xx xxxx | 10xx xxxx |
我们分别看三个从一个字节到三个字节的UTF-8编码例子:
实际字符 | 在Unicode字库序号的十六进制 | 在Unicode字库序号的二进制 | UTF-8编码后的二进制 | UTF-8编码后的十六进制 |
$ | 0024 | 010 0100 | 0010 0100 | 24 |
¢ | 00A2 | 000 1010 0010 | 1100 0010 1010 0010 | C2 A2 |
€ | 20AC | 0010 0000 1010 1100 | 1110 0010 1000 0010 1010 1100 | E2 82 AC |
细心的读者不难从以上的简单介绍中得出以下规律:
- 3个字节的UTF-8十六进制编码一定是以
E
开头的 - 2个字节的UTF-8十六进制编码一定是以
C
或D
开头的 - 1个字节的UTF-8十六进制编码一定是以比
8
小的数字开头的
String length in bytes in JavaScript
There is no way to do it in JavaScript natively.
If you know the character encoding, you can calculate it yourself though.
encodeURIComponent
assumes UTF-8 as the character encoding, so if you need that encoding, you can do,
function lengthInUtf8Bytes(str){
// Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.var m = encodeURIComponent(str).match(/%[89ABab]/g);
return str.length +(m ? m.length :0);
}
This should work because of the way UTF-8 encodes multi-byte sequences. The first encoded byte always starts with either a high bit of zero for a single byte sequence, or a byte whose first hex digit is C, D, E, or F. The second and subsequent bytes are the ones whose first two bits are 10. Those are the extra bytes you want to count in UTF-8.
If instead you need to understand the page encoding, you can use this trick:
function lengthInPageEncoding(s){
var a = document.createElement('A');
a.href ='#'+ s;
var sEncoded = a.href;
sEncoded = sEncoded.substring(sEncoded.indexOf('#')+1);
var m = sEncoded.match(/%[0-9a-f]{2}/g);
return sEncoded.length -(m ? m.length *2:0);
}
例子:
function lengthInUtf8Bytes(str) {
// Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
var m = encodeURIComponent(str).match(/%[89ABab]/g);
console.log(encodeURIComponent(str));
console.log(m);
return str.length + (m ? m.length : 0);
}
console.log(lengthInUtf8Bytes("心情好ab"));
结果:
%E5%BF%83%E6%83%85%E5%A5%BDab
["%B", "%8", "%8", "%8", "%A", "%B"]
11
内容参考:
http://cenalulu.github.io/linux/character-encoding/
http://stackoverflow.com/questions/5515869/string-length-in-bytes-in-javascript
相关推荐
在C#编程中,有时我们需要根据字节长度来截取字符串,这可能是因为要处理不同编码格式的数据,或者为了适应特定的传输限制。本篇将详细介绍如何在C#中按照字节长度截取字符串,并结合正则表达式进行操作。 首先,...
DatagramPacket dp=new DatagramPacket(str.getBytes(),str.length(), InetAddress.getByName("Localhost"),6000); ds.send(dp); ds.close(); } catch(Exception e){} } public static void main(String[] ...
### Java中的字节流 #### 一、字节流简介 在Java中,字节流是一种处理二进制数据的基本方式。它通过一系列类来实现数据的读取和写入功能,这些类主要继承自`InputStream`和`OutputStream`两个抽象类。字节流非常...
接着指定字符集(如UTF-8或GB2312),获取相应的编码对象,并将字符串转换为字节数组。最后,遍历字节数组并将其每个元素转换为十六进制字符串,同时可以根据参数选择是否在每个十六进制数之间插入分隔符。 ```...
在Java开发中,字符串(String)、十六进制表示的字符串以及字节数组(byte[])之间的转换是非常常见的需求,尤其是在处理网络通信、文件读写等场景下。本文将详细介绍如何在Java中实现这些数据类型之间的相互转换,...
根据给定文件的信息,本文将深入探讨如何在C#中实现一种高效的按字节截取字符串的方法,尤其针对包含单字节与双字节混合字符的情况。这种方法特别适用于处理中文等双字节字符与英文等单字节字符混合的情况。 ### 一...
根据给定文件的信息,本文将围绕“JS与Java中判断字符串中文、英文混合长度的方法”这一主题进行深入探讨。文章将分别介绍JavaScript和Java中如何处理包含中文字符和英文字符的混合字符串,并计算其等效长度。 ### ...
**MD5**(Message-Digest Algorithm 5)是一种广泛使用的散列算法,它将任意长度的输入转化为一个128位(16字节)的十六进制数字。尽管MD5不再被认为足够安全用于加密目的,但它仍然经常用于校验数据完整性。 **...
注意,我们使用了ASCII编码来获取密钥的前8个字节作为密钥和初始化向量(IV),并且在加密后将结果转换为Base64字符串,以便于在网络传输中使用。 在Java中,我们可以使用`javax.crypto.Cipher`和`javax.crypto....
MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,它能够将任意长度的输入数据转换为固定长度的128位(16字节)摘要,通常以32位十六进制数的形式表示。这个算法在信息安全、数据验证、密码存储等多个...
在C#编程语言中,字符串(string)与字节(byte)之间的转换是常见的操作之一。这类转换在处理网络通信、文件读写等场景时尤为常见。本文将详细介绍如何在C#中实现从string到byte及byte[]的有效转换,并探讨其中涉及...
byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(inputString); if (bytes.Length * 2) // 假设中文占两个字节 { return inputString; } int charCount = 0; string result = ""; for (int i = 0;...
在C#编程语言中,字符串(string)与字节数组(byte array)之间的转换是常见的操作,尤其在处理二进制数据、网络传输或文件读写时。本篇文章将详细解析C#中如何进行这两种数据类型的转换,并讨论转换过程中需要注意...
它能够将任意长度的数据转换为固定长度的128位(16字节)摘要,通常以32个十六进制字符表示。在Java中,MD5的实现主要依赖于`java.security.MessageDigest`类。 在Java中,对MD5的封装通常包括以下几个步骤: 1. *...
在C#编程中,字符串(string)与字节(byte[])之间的转换是常见的操作,特别是在处理网络传输、文件存储或数据解析时。本文将详细讲解C#中如何进行这两种类型之间的转换,并提供一些实用的方法。 首先,我们来看如何将...
在上面的代码中,我们可以看到C#使用System.Text.Encoding.UTF8.GetBytes方法将字符串转换为字节数组,而Java使用getBytes方法将字符串转换为字节数组。但是,这两种方法的输出结果不同。C#的输出结果为[230, 136, ...
在Java编程语言中,`...通过阅读和分析`TestString.java`文件,我们可以看到这些方法在实际代码中的应用,从而加深对它们的理解。在进行字符串操作时,应根据具体需求选择合适的方法,以优化性能和提高代码可读性。
MD5(Message-Digest Algorithm 5)是RSA数据安全公司设计并发布的一种散列函数,它能够接收任意长度的消息作为输入,并生成一个固定长度(通常是128位或16字节)的十六进制字符串作为输出。由于其计算速度快且安全...
但是,Java的字符串是Unicode的,`getBytes()`会根据指定的字符集编码字符串为字节数组。例如: ```java String str = "你好,世界"; int byteCount = 5; // 指定字节数 byte[] bytes = str.getBytes("UTF-8"); // ...