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 1Byte 2Byte3
0xxx xxxx  
110x xxxx10xx xxxx 
1110 xxxx10xx xxxx10xx xxxx

我们分别看三个从一个字节到三个字节的UTF-8编码例子:

实际字符在Unicode字库序号的十六进制在Unicode字库序号的二进制UTF-8编码后的二进制UTF-8编码后的十六进制
$0024010 01000010 010024
¢00A2000 1010 00101100 0010 1010 0010C2 A2
20AC0010 0000 1010 11001110 0010 1000 0010 1010 1100E2 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值