JS 获取文字字节长度,效果同java的String.getBytes().length

首先要了解下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字库中的序号

Byte 1 Byte 2 Byte3
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十六进制编码一定是以CD开头的
  • 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

猜你喜欢

转载自slnddd.iteye.com/blog/2324217