>  기사  >  웹 프론트엔드  >  Node.js 버퍼의 인코딩에 대해 이야기해 보겠습니다.

Node.js 버퍼의 인코딩에 대해 이야기해 보겠습니다.

青灯夜游
青灯夜游앞으로
2021-08-31 10:28:233471검색

이 기사는 Node.js 버퍼의 인코딩을 안내합니다. 도움이 되기를 바랍니다.

Node.js 버퍼의 인코딩에 대해 이야기해 보겠습니다.

컴퓨터의 가장 작은 단위는 비트(bit), 즉 0과 1이며, 이는 하드웨어에서 높은 수준과 낮은 수준으로 표현됩니다. 하지만 1비트만으로는 너무 적은 정보를 나타내기 때문에 8비트를 1바이트로 지정하고 그 이후에는 숫자, 문자열 등 다양한 정보를 바이트 단위로 저장하게 됩니다. [추천 학습: "nodejs tutorial"]

문자를 어떻게 저장하나요? 이는 인코딩에 의존합니다. 다른 문자는 다른 인코딩에 해당합니다. 그런 다음 렌더링이 필요할 때 해당 인코딩에 따라 글꼴 라이브러리를 확인한 다음 해당 문자의 그래픽을 렌더링합니다.

문자 집합

최초의 문자 집합(charset)은 ASCII 코드로 abc ABC 123과 기타 128개의 문자로 이루어져 있는데, 이는 컴퓨터가 미국에서 처음 발명되었기 때문입니다. 나중에 유럽에서는 ISO라는 문자 세트 표준 세트를 개발했으며, 나중에 중국에서는 GBK라는 문자 세트 표준 세트를 개발했습니다.

국제표준화기구(International Organization for Standardization)는 우리 각자가 하나를 가질 수 없다고 느꼈습니다. 그렇지 않으면 동일한 코드가 다른 문자 집합에서 다른 의미를 갖게 될 것이기 때문에 우리는 전 세계 대부분의 코드를 포함하여 각 문자가 고유한 고유한 코드를 갖도록 유니코드 코딩을 제안했습니다. 코드.

그러나 ASCII 코드는 저장하는 데 1바이트만 필요하고 GBK는 2바이트가 필요하며 일부 문자 세트는 3바이트가 필요합니다. 일부는 저장하는 데 1바이트만 필요하지만 2바이트는 상당히 공간을 낭비합니다. 따라서 utf-8, utf-16, utf-24 등과 같은 다양한 인코딩 방식이 있습니다.

utf-8, utf-16, utf-24는 모두 유니코드 인코딩이지만 구체적인 구현 계획은 다릅니다.

UTF-8 공간을 절약하기 위해 1~6바이트의 가변 길이 스토리지 솔루션이 설계되었습니다. UTF-16은 2바이트로 고정되고, UTF-24는 4바이트로 고정됩니다.

Node.js 버퍼의 인코딩에 대해 이야기해 보겠습니다.

마지막으로 UTF-8은 공간을 가장 적게 차지하기 때문에 널리 사용됩니다.

Node.js의 버퍼 인코딩

모든 언어는 문자 집합 인코딩 및 디코딩을 지원하며 Node.js도 동일합니다.

Buffer를 사용하여 Node.js에 바이너리 데이터를 문자열로 변환할 때 문자 세트를 지정해야 합니다. Buffer's from, byteLength, lastIndexOf 및 기타 메소드는 인코딩 지정을 지원합니다.

특정 지원 포함:

utf8, ucs2, utf16le, latin1, ascii, base64, hex

일부 학생들은 다음을 찾을 수 있습니다. base64 및 hex는 문자 집합이 아닙니다. 왜 여기에 나타납니까?

예, 문자 세트 외에도 바이트-문자 인코딩 체계에는 일반 텍스트 문자로 변환하기 위한 base64와 16진수로 변환하기 위한 16진수가 포함됩니다.

이것이 Node.js가 이를 charset 대신 인코딩이라고 부르는 이유입니다. 지원되는 인코딩 및 디코딩 구성표는 단순한 문자 세트가 아니기 때문입니다.

인코딩을 지정하지 않은 경우 기본값은 utf8입니다.

const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');

console.log(buf.toString());// hello world

encoding source code

인코딩에 대한 Node.js 소스 코드를 살펴보았습니다.

이 섹션에서는 인코딩을 구현합니다: https://github.com/nodejs/node/blob/master/lib/ buffer.js #L587-L726

각 인코딩이 인코딩, 인코딩Val, byteLength, 쓰기, 슬라이스, indexOf API를 구현하는 것을 볼 수 있습니다. 이러한 API는 서로 다른 인코딩 체계를 사용하므로 Node.js는 다음에 따라 서로 다른 객체를 반환합니다. 다형성 아이디어인 들어오는 인코딩입니다.

const encodingOps = {
  utf8: {
    encoding: 'utf8',
    encodingVal: encodingsMap.utf8,
    byteLength: byteLengthUtf8,
    write: (buf, string, offset, len) => buf.utf8Write(string, offset, len),
    slice: (buf, start, end) => buf.utf8Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir)
  },
  ucs2: {
    encoding: 'ucs2',
    encodingVal: encodingsMap.utf16le,
    byteLength: (string) => string.length * 2,
    write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len),
    slice: (buf, start, end) => buf.ucs2Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir)
  },
  utf16le: {
    encoding: 'utf16le',
    encodingVal: encodingsMap.utf16le,
    byteLength: (string) => string.length * 2,
    write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len),
    slice: (buf, start, end) => buf.ucs2Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir)
  },
  latin1: {
    encoding: 'latin1',
    encodingVal: encodingsMap.latin1,
    byteLength: (string) => string.length,
    write: (buf, string, offset, len) => buf.latin1Write(string, offset, len),
    slice: (buf, start, end) => buf.latin1Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir)
  },
  ascii: {
    encoding: 'ascii',
    encodingVal: encodingsMap.ascii,
    byteLength: (string) => string.length,
    write: (buf, string, offset, len) => buf.asciiWrite(string, offset, len),
    slice: (buf, start, end) => buf.asciiSlice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.ascii),
                    byteOffset,
                    encodingsMap.ascii,
                    dir)
  },
  base64: {
    encoding: 'base64',
    encodingVal: encodingsMap.base64,
    byteLength: (string) => base64ByteLength(string, string.length),
    write: (buf, string, offset, len) => buf.base64Write(string, offset, len),
    slice: (buf, start, end) => buf.base64Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.base64),
                    byteOffset,
                    encodingsMap.base64,
                    dir)
  },
  hex: {
    encoding: 'hex',
    encodingVal: encodingsMap.hex,
    byteLength: (string) => string.length >>> 1,
    write: (buf, string, offset, len) => buf.hexWrite(string, offset, len),
    slice: (buf, start, end) => buf.hexSlice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.hex),
                    byteOffset,
                    encodingsMap.hex,
                    dir)
  }
};
function getEncodingOps(encoding) {
  encoding += '';
  switch (encoding.length) {
    case 4:
      if (encoding === 'utf8') return encodingOps.utf8;
      if (encoding === 'ucs2') return encodingOps.ucs2;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'utf8') return encodingOps.utf8;
      if (encoding === 'ucs2') return encodingOps.ucs2;
      break;
    case 5:
      if (encoding === 'utf-8') return encodingOps.utf8;
      if (encoding === 'ascii') return encodingOps.ascii;
      if (encoding === 'ucs-2') return encodingOps.ucs2;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'utf-8') return encodingOps.utf8;
      if (encoding === 'ascii') return encodingOps.ascii;
      if (encoding === 'ucs-2') return encodingOps.ucs2;
      break;
    case 7:
      if (encoding === 'utf16le' ||
          StringPrototypeToLowerCase(encoding) === 'utf16le')
        return encodingOps.utf16le;
      break;
    case 8:
      if (encoding === 'utf-16le' ||
          StringPrototypeToLowerCase(encoding) === 'utf-16le')
        return encodingOps.utf16le;
      break;
    case 6:
      if (encoding === 'latin1' || encoding === 'binary')
        return encodingOps.latin1;
      if (encoding === 'base64') return encodingOps.base64;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'latin1' || encoding === 'binary')
        return encodingOps.latin1;
      if (encoding === 'base64') return encodingOps.base64;
      break;
    case 3:
      if (encoding === 'hex' || StringPrototypeToLowerCase(encoding) === 'hex')
        return encodingOps.hex;
      break;
  }
}

Summary

컴퓨터에서 데이터를 저장하는 최소 단위는 비트이지만 정보를 저장하는 최소 단위는 바이트입니다. 인코딩과 문자 간의 매핑 관계를 기반으로 ascii, iso를 포함한 다양한 문자 세트가 구현됩니다. , gbk 등 및 국제 표준화 기구에서는 모든 문자를 포함하도록 유니코드를 제안했습니다. utf-8, utf-16, utf-24와 같은 여러 가지 유니코드 구현 솔루션이 있습니다. 그 중 utf-8은 가변 길이이고 저장 용량이 가장 작아 널리 사용됩니다.

Node.js는 Buffer를 통해 바이너리 데이터를 저장하고, 이를 문자열로 변환할 때 인코딩 체계를 지정해야 합니다. 이 인코딩 체계에는 문자 집합(문자 집합)이 포함될 뿐만 아니라 다음을 포함한 16진수 및 base64 체계도 지원됩니다.

utf8, ucs2, utf16le, latin1, ascii, base64, hex

Node.js 인코딩 소스 코드를 살펴본 결과 각 인코딩 체계가 다형성 아이디어인 일련의 API를 구현한다는 것을 발견했습니다.

인코딩은 Node.js를 배울 때 자주 접하는 개념인데, Node.js의 인코딩에는 문자 집합만 포함되는 것이 아닙니다. 이 글이 모든 사람이 인코딩과 문자 집합을 이해하는 데 도움이 되기를 바랍니다.

더 많은 프로그래밍 관련 지식을 보려면

프로그래밍 소개를 방문하세요! !

위 내용은 Node.js 버퍼의 인코딩에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제