UTF-8编码算法如何在8位块(JavaScript)上工作?

UTF-8编码算法如何在8位块(JavaScript)上工作?,javascript,encoding,utf-8,bit-manipulation,Javascript,Encoding,Utf 8,Bit Manipulation,我正在看: 在JavaScript中,它似乎利用了JavaScript中的数字(我认为)大约32位长这一事实。所以它做了一些我不熟悉的位处理,得到了编码的值。与解码功能相同: function decodeSymbol() { var byte1; var byte2; var byte3; var byte4; var codePoint; if (byteIndex > byteCount) { throw Error('Invalid byte in

我正在看:

在JavaScript中,它似乎利用了JavaScript中的数字(我认为)大约32位长这一事实。所以它做了一些我不熟悉的位处理,得到了编码的值。与
解码功能相同:

function decodeSymbol() {
  var byte1;
  var byte2;
  var byte3;
  var byte4;
  var codePoint;

  if (byteIndex > byteCount) {
    throw Error('Invalid byte index');
  }

  if (byteIndex == byteCount) {
    return false;
  }

  // Read first byte
  byte1 = byteArray[byteIndex] & 0xFF;
  byteIndex++;

  // 1-byte sequence (no continuation bytes)
  if ((byte1 & 0x80) == 0) {
    return byte1;
  }

  // 2-byte sequence
  if ((byte1 & 0xE0) == 0xC0) {
    byte2 = readContinuationByte();
    codePoint = ((byte1 & 0x1F) << 6) | byte2;
    if (codePoint >= 0x80) {
      return codePoint;
    } else {
      throw Error('Invalid continuation byte');
    }
  }

  // 3-byte sequence (may include unpaired surrogates)
  if ((byte1 & 0xF0) == 0xE0) {
    byte2 = readContinuationByte();
    byte3 = readContinuationByte();
    codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
    if (codePoint >= 0x0800) {
      checkScalarValue(codePoint);
      return codePoint;
    } else {
      throw Error('Invalid continuation byte');
    }
  }

  // 4-byte sequence
  if ((byte1 & 0xF8) == 0xF0) {
    byte2 = readContinuationByte();
    byte3 = readContinuationByte();
    byte4 = readContinuationByte();
    codePoint = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0C) |
      (byte3 << 0x06) | byte4;
    if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
      return codePoint;
    }
  }

  throw Error('Invalid UTF-8 detected');
}
函数解码符号(){
var字节1;
var字节2;
var字节3;
var字节4;
var码点;
if(字节索引>字节计数){
抛出错误(“无效字节索引”);
}
if(字节索引==字节计数){
返回false;
}
//读取第一个字节
字节1=字节数组[byteIndex]&0xFF;
byteIndex++;
//1字节序列(无连续字节)
if((字节1和0x80)==0){
返回字节1;
}
//2字节序列
if((字节1和0xE0)==0xC0){
字节2=readContinuationByte();
代码点=((字节1和0x1F)=0x80){
返回码点;
}否则{
抛出错误(“无效的连续字节”);
}
}
//3字节序列(可能包括未配对的代理)
if((字节1和0xF0)==0xE0){
字节2=readContinuationByte();
字节3=readContinuationByte();

codePoint=((byte1&0x0F)JS整数具有32位二进制运算符,因此您可以在一个数字中安全地使用4 x 8位(4字节)。这是解码器作为参数接收的内容


UTF-8编码的大小是可变的。如果代码点仅采用7位(=ASCII),则它将适合一个字节,该字节具有前导零,以指示它只有一个字节:

  0XXXXXXXX
现在要检查码点是否只有一个字节,可以检查高位字节中是否设置了位。这可以通过将码点与
0xFFFFF80
进行比较来完成,该值设置了除最后8位之外的所有位。因此,如果按位and导致不相等的0,则高位字节中的某个位置设置了位

  1111111111111111111110000000 &
                      0XXXXXXX
   = 0

现在,如果超过7位,第一个字节包含字节数,以下所有字节在开头包含一个
01
序列,即4个字节:

  11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
例如,现在要获得上面8个编码位,可以右移18:

  1110XXX 10XXXXX

(UTF-8标准)并有很好的描述。是的,对JS数的按位操作就像对32位整数进行的操作一样
  1110XXX 10XXXXX