CC0 1.0 Universal. To the extent possible under law, the editor has waived all copyright and related or neighboring rights to this work. In addition, as of 22 February 2013, the editor has made this specification available under the Open Web Foundation Agreement Version 1.0, which is available at http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
While encodings have been defined to some extent, implementations have not always implemented them in the same way, have not always used the same labels, and often differ in dealing with undefined and former proprietary areas of encodings. This specification attempts to fill those gaps so that new implementations do not have to reverse engineer encoding implementations of the market leaders and existing implementations can converge.
This specification is primarily intended for dealing with legacy content, it requires new content and formats to use the utf-8 encoding exclusively.
All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
User agents may impose implementation-specific limits on otherwise unconstrained inputs, e.g. to prevent denial of service attacks, to guard against running out of memory, or to work around platform-specific limitations.
Hexadecimal numbers are prefixed with "0x".
In equations, all numbers are integers, addition is represented by "+", subtraction by "−", multiplication by "×", division by "/", calculating the remainder of a division (also known as modulo) by "%", exponentiation by "bn", arithmetic left shifts by "<<", arithmetic right shifts by ">>", bitwise AND by "&", and bitwise OR by "|".
A byte is a sequence of eight bits, represented as a double-digit hexadecimal number in the range 0x00 to 0xFF.
A code point is a Unicode code point and is represented as a four-to-six digit hexadecimal number, typically prefixed with "U+". In equations and indexes code points are prefixed with "0x". [UNICODE]
The ASCII whitespace are code points U+0009, U+000A, U+000C, U+000D, and U+0020.
A string is a sequence of code points.
Comparing two strings in an ASCII case-insensitive manner means comparing them exactly, code point for code point, except that the characters in the range U+0041 to U+005A (i.e. LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z) and the corresponding characters in the range U+0061 to U+007A (i.e. LATIN SMALL LETTER A to LATIN SMALL LETTER Z) are considered to also match.
An encoding defines a mapping from a code point sequence to a byte sequence (and vice versa). Each encoding has a name, and one or more labels.
Each encoding also has a decoder and encoder algorithm.
A decoder algorithm takes a byte stream and emits a code point stream. The byte pointer is initially zero, pointing to the first byte in the stream. It cannot be negative. It can be increased and decreased to point to other bytes in the stream. The EOF byte is a conceptual byte representing the end of the stream. The byte pointer cannot point beyond the EOF byte. The EOF code point is a conceptual code point that is emitted once the byte stream is handled in its entirety. A decoder error indicates an error in the byte stream. Unless stated otherwise, emitting a decoder error must emit code point U+FFFD. A decoder must be invoked again when the word continue is used, when one or more code points are emitted of which none is the EOF code point, or when a decoder error is emitted.
An XML processor would halt upon the first decoder error emitted.
An encoder algorithm takes a code point stream and emits a byte stream. It fails when a code point is passed for which it does not have a corresponding byte (sequence). Analogously to a decoder, it has a code point pointer and encoder error. An encoder must be invoked again when the word continue is used, or when one or more bytes are emitted of which none is the EOF byte. Unless stated otherwise, when an encoder error is emitted the encoder terminates.
HTML forms and URLs require non-terminating encoders and have therefore special handling whenever an encoder error is reached. Instead of terminating the encoder one or more code points in the range U+0000 to U+007F are inserted into the code point stream at code point pointer after encoder error is emitted.
The table below lists all encodings and their labels user agents must support. User agents must not support any other encodings or labels.
Authors must use the utf-8 encoding and must use the
"utf-8" label to identify it.
New protocols and formats must use the utf-8 encoding
exclusively. If these protocols and formats need to expose the encoding's
label, they must expose it as "utf-8".
To get an encoding from a string label, run these steps:
Remove any leading and trailing ASCII whitespace from label.
If label is an ASCII case-insensitive match for any of the labels listed in the table below, return the corresponding encoding, and return failure otherwise.
In violation of section 1.4 of Unicode Technical Standard #22 this is a much simpler and more restrictive matching algorithm, as that is found to be necessary to be compatible with deployed content.
| Name | Labels |
|---|---|
| The Encoding | |
| utf-8 | "unicode-1-1-utf-8"
|
"utf-8"
| |
"utf8"
| |
| Legacy single-byte encodings | |
| ibm866 | "866"
|
"cp866"
| |
"csibm866"
| |
"ibm866"
| |
| iso-8859-2 | "csisolatin2"
|
"iso-8859-2"
| |
"iso-ir-101"
| |
"iso8859-2"
| |
"iso88592"
| |
"iso_8859-2"
| |
"iso_8859-2:1987"
| |
"l2"
| |
"latin2"
| |
| iso-8859-3 | "csisolatin3"
|
"iso-8859-3"
| |
"iso-ir-109"
| |
"iso8859-3"
| |
"iso88593"
| |
"iso_8859-3"
| |
"iso_8859-3:1988"
| |
"l3"
| |
"latin3"
| |
| iso-8859-4 | "csisolatin4"
|
"iso-8859-4"
| |
"iso-ir-110"
| |
"iso8859-4"
| |
"iso88594"
| |
"iso_8859-4"
| |
"iso_8859-4:1988"
| |
"l4"
| |
"latin4"
| |
| iso-8859-5 | "csisolatincyrillic"
|
"cyrillic"
| |
"iso-8859-5"
| |
"iso-ir-144"
| |
"iso8859-5"
| |
"iso88595"
| |
"iso_8859-5"
| |
"iso_8859-5:1988"
| |
| iso-8859-6 | "arabic"
|
"asmo-708"
| |
"csiso88596e"
| |
"csiso88596i"
| |
"csisolatinarabic"
| |
"ecma-114"
| |
"iso-8859-6"
| |
"iso-8859-6-e"
| |
"iso-8859-6-i"
| |
"iso-ir-127"
| |
"iso8859-6"
| |
"iso88596"
| |
"iso_8859-6"
| |
"iso_8859-6:1987"
| |
| iso-8859-7 | "csisolatingreek"
|
"ecma-118"
| |
"elot_928"
| |
"greek"
| |
"greek8"
| |
"iso-8859-7"
| |
"iso-ir-126"
| |
"iso8859-7"
| |
"iso88597"
| |
"iso_8859-7"
| |
"iso_8859-7:1987"
| |
"sun_eu_greek"
| |
| iso-8859-8 | "csiso88598e"
|
"csisolatinhebrew"
| |
"hebrew"
| |
"iso-8859-8"
| |
"iso-8859-8-e"
| |
"iso-ir-138"
| |
"iso8859-8"
| |
"iso88598"
| |
"iso_8859-8"
| |
"iso_8859-8:1988"
| |
"visual"
| |
| iso-8859-8-i | "csiso88598i"
|
"iso-8859-8-i"
| |
"logical"
| |
| iso-8859-10 | "csisolatin6"
|
"iso-8859-10"
| |
"iso-ir-157"
| |
"iso8859-10"
| |
"iso885910"
| |
"l6"
| |
"latin6"
| |
| iso-8859-13 | "iso-8859-13"
|
"iso8859-13"
| |
"iso885913"
| |
| iso-8859-14 | "iso-8859-14"
|
"iso8859-14"
| |
"iso885914"
| |
| iso-8859-15 | "csisolatin9"
|
"iso-8859-15"
| |
"iso8859-15"
| |
"iso885915"
| |
"iso_8859-15"
| |
"l9"
| |
| iso-8859-16 | "iso-8859-16"
|
| koi8-r | "cskoi8r"
|
"koi"
| |
"koi8"
| |
"koi8-r"
| |
"koi8_r"
| |
| koi8-u | "koi8-u"
|
| macintosh | "csmacintosh"
|
"mac"
| |
"macintosh"
| |
"x-mac-roman"
| |
| windows-874 | "dos-874"
|
"iso-8859-11"
| |
"iso8859-11"
| |
"iso885911"
| |
"tis-620"
| |
"windows-874"
| |
| windows-1250 | "cp1250"
|
"windows-1250"
| |
"x-cp1250"
| |
| windows-1251 | "cp1251"
|
"windows-1251"
| |
"x-cp1251"
| |
| windows-1252 | "ansi_x3.4-1968"
|
"ascii"
| |
"cp1252"
| |
"cp819"
| |
"csisolatin1"
| |
"ibm819"
| |
"iso-8859-1"
| |
"iso-ir-100"
| |
"iso8859-1"
| |
"iso88591"
| |
"iso_8859-1"
| |
"iso_8859-1:1987"
| |
"l1"
| |
"latin1"
| |
"us-ascii"
| |
"windows-1252"
| |
"x-cp1252"
| |
| windows-1253 | "cp1253"
|
"windows-1253"
| |
"x-cp1253"
| |
| windows-1254 | "cp1254"
|
"csisolatin5"
| |
"iso-8859-9"
| |
"iso-ir-148"
| |
"iso8859-9"
| |
"iso88599"
| |
"iso_8859-9"
| |
"iso_8859-9:1989"
| |
"l5"
| |
"latin5"
| |
"windows-1254"
| |
"x-cp1254"
| |
| windows-1255 | "cp1255"
|
"windows-1255"
| |
"x-cp1255"
| |
| windows-1256 | "cp1256"
|
"windows-1256"
| |
"x-cp1256"
| |
| windows-1257 | "cp1257"
|
"windows-1257"
| |
"x-cp1257"
| |
| windows-1258 | "cp1258"
|
"windows-1258"
| |
"x-cp1258"
| |
| x-mac-cyrillic | "x-mac-cyrillic"
|
"x-mac-ukrainian"
| |
| Legacy multi-byte Chinese (simplified) encodings | |
| gbk | "chinese"
|
"csgb2312"
| |
"csiso58gb231280"
| |
"gb2312"
| |
"gb_2312"
| |
"gb_2312-80"
| |
"gbk"
| |
"iso-ir-58"
| |
"x-gbk"
| |
| gb18030 | "gb18030"
|
| hz-gb-2312 | "hz-gb-2312"
|
| Legacy multi-byte Chinese (traditional) encodings | |
| big5 | "big5"
|
"big5-hkscs"
| |
"cn-big5"
| |
"csbig5"
| |
"x-x-big5"
| |
| Legacy multi-byte Japanese encodings | |
| euc-jp | "cseucpkdfmtjapanese"
|
"euc-jp"
| |
"x-euc-jp"
| |
| iso-2022-jp | "csiso2022jp"
|
"iso-2022-jp"
| |
| shift_jis | "csshiftjis"
|
"ms_kanji"
| |
"shift-jis"
| |
"shift_jis"
| |
"sjis"
| |
"windows-31j"
| |
"x-sjis"
| |
| Legacy multi-byte Korean encodings | |
| euc-kr | "cseuckr"
|
"csksc56011987"
| |
"euc-kr"
| |
"iso-ir-149"
| |
"korean"
| |
"ks_c_5601-1987"
| |
"ks_c_5601-1989"
| |
"ksc5601"
| |
"ksc_5601"
| |
"windows-949"
| |
| iso-2022-kr | "csiso2022kr"
|
"iso-2022-kr"
| |
| Legacy miscellaneous encodings | |
| replacement | "iso-2022-cn"
|
"iso-2022-cn-ext"
| |
| utf-16be | "utf-16be"
|
| utf-16le | "utf-16"
|
"utf-16le"
| |
| x-user-defined | "x-user-defined"
|
All encodings and their labels are also available as non-normative encodings.json resource.
Most legacy encodings make use of an index. An index is an ordered list of pointers and corresponding code points. Within an index pointers are unique and code points can be duplicated.
To find the pointers and their corresponding code points in an index, let lines be the result of splitting the resource's contents on U+000A. Then remove each item in lines that is the empty string or starts with U+0023. Then the pointers and their corresponding code points are found by splitting each item in lines on U+0009. The first subitem is the pointer (as a decimal number) and the second is the corresponding code point (as a hexadecimal number). Other subitems are not relevant.
The index code point for pointer in index is the code point corresponding to pointer in index, or null if pointer is not in index.
The index pointer for code point in index is the first pointer corresponding to code point in index, or null if code point is not in index.
These are the indexes defined by this specification, excluding index single-byte:
| Index | Notes | |
|---|---|---|
| index big5 | index-big5.txt | This matches the Big5 standard in combination with the Hong Kong Supplementary Character Set and other common extensions. |
| index euc-kr | index-euc-kr.txt | This matches the KS X 1001 standard and the Unified Hangul Code, more commonly known together as Windows Codepage 949. |
| index gbk | index-gbk.txt | This matches the GB18030 standard for code points encoded as two bytes. |
| index gb18030 | index-gb18030.txt | This index works different from all others. Listing all code points would result in over a million items whereas they can be represented neatly in 207 ranges combined with trivial limit checks. It therefore only superficially matches the GB18030 standard for code points encoded as four bytes. See also index gb18030 code point and index gb18030 pointer below. |
| index jis0208 | index-jis0208.txt | This is the JIS X 0208 standard including formerly proprietary extensions from IBM and NEC. |
| index jis0212 | index-jis0212.txt | This is the JIS X 0212 standard. |
The index gb18030 code point for pointer is the return value of these steps:
If pointer is greater than 39419 and less than 189000, or pointer is greater than 1237575, return null.
Let offset be the last pointer in index gb18030 that is equal to or less than pointer and let code point offset be its corresponding code point.
Return a code point whose value is code point offset + pointer − offset.
The index gb18030 pointer for code point is the return value of these steps:
Let offset be the last code point in index gb18030 that is equal to or less than code point and let pointer offset be its corresponding pointer.
Return a pointer whose value is pointer offset + code point − offset.
All indexes are also available as non-normative indexes.json resource. (index gb18030 has a slightly different format here, to be able to represent ranges.)
The algorithms decode, utf-8 decode, and encode are intended for usage by other specifications. utf-8 decode is to be used by new formats. The get an encoding algorithm can be used first to turn a label into an encoding.
To decode a byte stream stream using fallback encoding encoding, run these steps:
Let offset be 0.
For each of the rows in the following table, starting with the first one and going down, if the first bytes of stream match all the bytes given in the first column (ergo stream contains at least two or three bytes), then set encoding to the encoding given in the cell in the second column of that row, and set offset to the offset given in the cell in the third column of that row.
| Byte order mark | Encoding | Offset |
|---|---|---|
| 0xFF 0xFE | utf-16le | 2 |
| 0xFE 0xFF | utf-16be | 2 |
| 0xEF 0xBB 0xBF | utf-8 | 3 |
For compatibility with deployed content, the byte order mark (also known as BOM) is considered more authoritative than anything else.
Return the result of running encoding's decoder with byte pointer set to offset, on stream.
To utf-8 decode a byte stream stream, run these steps:
Let offset be 0.
If stream contains at least three bytes and its first three bytes match 0xEF 0xBB 0xBF, set offset to 3.
Return the result of running the utf-8 decoder with byte pointer set to offset, on stream.
To encode a code point stream stream using encoding encoding, return the result of running encoding's encoder on stream.
To utf-8 encode a code point stream stream, return the result of encoding stream using encoding utf-8.
If the input to this algorithm stems from a DOMString, the convert a DOMString to a sequence of Unicode characters from Web IDL is to be used first.
This section uses terminology from the DOM, Typed Arrays, and Web IDL. Non-browser implementations are not required to implement this API. [DOM] [TYPEDARRAY] [WEBIDL]
The following example uses the TextEncoder object to encode
an array of strings into an
ArrayBuffer. The result is a
Uint8Array containing the number
of strings (as a Uint32Array),
followed by the length of the first string (as a
Uint32Array), the
utf-8 encoded string data, the length of the second string (as
a Uint32Array), the string data,
and so on.
function encodeArrayOfStrings(strings, encoding) {
var encoder, encoded, len, i, bytes, view, offset;
encoder = TextEncoder(encoding);
encoded = [];
len = Uint32Array.BYTES_PER_ELEMENT;
for (i = 0; i < strings.length; i += 1) {
len += Uint32Array.BYTES_PER_ELEMENT;
encoded[i] = TextEncoder(encoding).encode(strings[i]);
len += encoded[i].byteLength;
}
bytes = new Uint8Array(len);
view = new DataView(bytes.buffer);
offset = 0;
view.setUint32(offset, strings.length);
offset += Uint32Array.BYTES_PER_ELEMENT;
for (i = 0; i < encoded.length; i += 1) {
len = encoded[i].byteLength;
view.setUint32(offset, len);
offset += Uint32Array.BYTES_PER_ELEMENT;
bytes.set(encoded[i], offset);
offset += len;
}
return bytes.buffer;
}
The following example decodes an
ArrayBuffer containing data
encoded in the format produced by the previous example back into an array
of strings.
function decodeArrayOfStrings(buffer, encoding) {
var decoder, view, offset, num_strings, strings, i, len;
decoder = TextDecoder(encoding);
view = new DataView(buffer);
offset = 0;
strings = [];
num_strings = view.getUint32(offset);
offset += Uint32Array.BYTES_PER_ELEMENT;
for (i = 0; i < num_strings; i += 1) {
len = view.getUint32(offset);
offset += Uint32Array.BYTES_PER_ELEMENT;
strings[i] = decoder.decode(
new DataView(view.buffer, offset, len));
offset += len;
}
return strings;
}
TextDecoderdictionary TextDecoderOptions {
boolean fatal = false;
};
dictionary TextDecodeOptions {
boolean stream = false;
};
[Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options)]
interface TextDecoder {
readonly attribute DOMString encoding;
DOMString decode();
DOMString decode(ArrayBufferView input, optional TextDecodeOptions options);
};
A TextDecoder object has an associated
encoding, encoding state, stream,
BOM seen flag (initially unset), fatal flag (initially unset)
and streaming flag (initially unset).
decoder = new TextDecoder([label = "utf-8" [, options]])
Returns a new TextDecoder object.
If label is either not a label or is a
label for replacement,
throws a
TypeError.
decoder . encoding
Returns encoding's name.
decoder . decode([input [, options]])
Returns the result of running encoding's
decoder. If options's
stream is set to true the method can be invoked
multiple times to process a fragmented stream.
If the fatal flag is set and encoding's
decoder emits a decoder error,
throws an
"EncodingError".
The
TextDecoder(label, options)
constructor must run these steps:
Let encoding be the result of getting an encoding from label.
If encoding is failure or replacement,
throw a TypeError.
Let dec be a new TextDecoder object.
Set dec's encoding to encoding.
Set dec's encoding state to the default values of dec's encoding's decoder's associated variables.
If options's fatal member is
true, set dec's fatal flag.
Return dec.
The encoding
attribute must return encoding's name.
The
decode(input, options)
method must run these steps:
If the streaming flag is unset, set the encoding state to the default values of the encoding's decoder's associated variables and empty the stream.
If options's stream is true,
set the streaming flag, and unset the streaming flag
otherwise.
If input is given, then given
input's buffer,
byteOffset, and byteLength, append
byteLength bytes from buffer,
starting at byteOffset, to the stream.
If the BOM seen flag is unset, and the stream either holds at least two bytes, or at least three bytes if the encoding is utf-8, then set the BOM seen flag, and for each of the rows in the following table, starting with the first one and going down, if the first bytes of the stream match all the bytes given in the first column, and the encoding matches the encoding given in the cell in the second column of that row, then remove those bytes at the start of the stream.
| Byte order mark | Encoding |
|---|---|
| 0xFF 0xFE | utf-16le |
| 0xFE 0xFF | utf-16be |
| 0xEF 0xBB 0xBF | utf-8 |
This algorithm is intentionally different from the decode algorithm used by the rest of the platform to give API users more control.
If the streaming flag is unset, append the EOF byte to the stream.
Return the output of running encoding's decoder on
the stream. If the fatal flag is set and
encoding's decoder emits a decoder error,
throw a
"EncodingError".
In addition to the reason given above with respect to the byte order mark, this also does not use the encode algorithm as it assumes a continuous stream rather than one delivered in fragments.
TextEncoderdictionary TextEncodeOptions {
boolean stream = false;
};
[Constructor(optional DOMString utfLabel = "utf-8")]
interface TextEncoder {
readonly attribute DOMString encoding;
Uint8Array encode(optional DOMString input = "", optional TextEncodeOptions options);
};
A TextEncoder object has an associated
encoding, encoding state, stream, and
streaming flag (initially unset).
encoder = new TextEncoder([utfLabel = "utf-8"])
Returns a new TextEncoder object.
If utfLabel is not a label for
utf-8, utf-16le, or utf-16be,
throws a
TypeError.
encoder . encoding
Returns encoding's name.
encoder . encode([input [, options]])
Returns the result of running encoding's
encoder. If options's
stream is set to true, the method can be invoked
multiple times to process a fragmented stream.
The
TextEncoder(utfLabel)
constructor must run these steps:
Let encoding be the result of getting an encoding from utfLabel.
If encoding is failure, or is none of
utf-8, utf-16le, and utf-16be,
throw a TypeError.
Let enc be a new TextEncoder object.
Set enc's encoding to encoding.
Set enc's encoding state to the default values of enc's encoding's encoder's associated variables.
Return enc.
The encoding
attribute must return encoding's name.
The
encode(input, options)
method must run these steps:
If the streaming flag is unset, then set the encoding state to the default values of the encoding's encoder's associated variables, and empty the stream.
If options's stream is true,
set the streaming flag, and unset the streaming flag
otherwise.
Append the result of converting input to Unicode to the stream.
If the streaming flag is unset, append the EOF code point to the stream.
Let bytes be the output of running encoding's encoder on the stream.
This does not use the encode algorithm as it assumes a continuous stream rather than one delivered in fragments.
Return a
Uint8Array object wrapping an
ArrayBuffer containing
bytes.
The utf-8 code point, utf-8 bytes seen, and utf-8 bytes needed concepts are all initially 0. The utf-8 lower boundary is initially 0x80 and the utf-8 upper boundary is initially 0xBF.
The utf-8 decoder (decoder for utf-8) is:
Let byte be the value at byte pointer.
If byte is the EOF byte and utf-8 bytes needed is not 0, set utf-8 bytes needed to 0 and emit a decoder error.
If byte is the EOF byte, emit the EOF code point.
Increase the byte pointer by one.
If utf-8 bytes needed is 0, based on byte:
Emit a code point whose value is byte.
Set utf-8 bytes needed to 1 and utf-8 code point to byte − 0xC0.
If byte is 0xE0, set utf-8 lower boundary to 0xA0.
If byte is 0xED, set utf-8 upper boundary to 0x9F.
Set utf-8 bytes needed to 2 and utf-8 code point to byte − 0xE0.
If byte is 0xF0, set utf-8 lower boundary to 0x90.
If byte is 0xF4, set utf-8 upper boundary to 0x8F.
Set utf-8 bytes needed to 3 and utf-8 code point to byte − 0xF0.
Emit a decoder error.
Then (byte is in the range 0xC2 to 0xF4) set utf-8 code point to utf-8 code point × 64utf-8 bytes needed and continue.
If byte is not in the range utf-8 lower boundary to utf-8 upper boundary, run these substeps:
Set utf-8 code point, utf-8 bytes needed, and utf-8 bytes seen to 0, set utf-8 lower boundary to 0x80, and set utf-8 upper boundary to 0xBF.
Decrease the byte pointer by one.
Emit a decoder error.
Set utf-8 lower boundary to 0x80 and utf-8 upper boundary to 0xBF.
Increase utf-8 bytes seen by one and set utf-8 code point to utf-8 code point + (byte − 0x80) × 64utf-8 bytes needed − utf-8 bytes seen.
If utf-8 bytes seen is not equal to utf-8 bytes needed, continue.
Let code point be utf-8 code point.
Set utf-8 code point, utf-8 bytes needed, and utf-8 bytes seen to 0.
Emit a code point whose value is code point.
The constraints in the utf-8 decoder above match “Best Practices for Using U+FFFD” from the Unicode standard. No other behavior is permitted per the Encoding Standard (other algorithms that achieve the same result are obviously fine, even encouraged).
The utf-8 encoder (encoder for utf-8) is:
Let code point be the value at code point pointer.
If code point is in the range 0xD800 to 0xDFFF, emit an encoder error.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
Set count and offset based on the range code point is in:
Let bytes be a list of bytes whose first byte is code point / 64count + offset.
Run these substeps while count is greater than 0:
Set temp to code point / 64count − 1.
Append to bytes 0x80 + (temp % 64).
Decrease count by one.
Emit bytes bytes, in list order.
An encoding where each byte is either a single code point or nothing, is a single-byte encoding. Single-byte encodings share the decoder and encoder. Index single-byte, as referenced by the single-byte decoder and single-byte encoder, is defined by the following table, and depends on the single-byte encoding in use. All but two single-byte encodings have a unique index.
| Name | Index |
|---|---|
| ibm866 | index-ibm866.txt |
| iso-8859-2 | index-iso-8859-2.txt |
| iso-8859-3 | index-iso-8859-3.txt |
| iso-8859-4 | index-iso-8859-4.txt |
| iso-8859-5 | index-iso-8859-5.txt |
| iso-8859-6 | index-iso-8859-6.txt |
| iso-8859-7 | index-iso-8859-7.txt |
| iso-8859-8 | index-iso-8859-8.txt |
| iso-8859-8-i | index-iso-8859-8.txt |
| iso-8859-10 | index-iso-8859-10.txt |
| iso-8859-13 | index-iso-8859-13.txt |
| iso-8859-14 | index-iso-8859-14.txt |
| iso-8859-15 | index-iso-8859-15.txt |
| iso-8859-16 | index-iso-8859-16.txt |
| koi8-r | index-koi8-r.txt |
| koi8-u | index-koi8-u.txt |
| macintosh | index-macintosh.txt |
| windows-874 | index-windows-874.txt |
| windows-1250 | index-windows-1250.txt |
| windows-1251 | index-windows-1251.txt |
| windows-1252 | index-windows-1252.txt |
| windows-1253 | index-windows-1253.txt |
| windows-1254 | index-windows-1254.txt |
| windows-1255 | index-windows-1255.txt |
| windows-1256 | index-windows-1256.txt |
| windows-1257 | index-windows-1257.txt |
| windows-1258 | index-windows-1258.txt |
| x-mac-cyrillic | index-x-mac-cyrillic.txt |
iso-8859-8 and iso-8859-8-i are distinct encoding names, because iso-8859-8 has influence on the layout direction. And although historically this might have been the case for iso-8859-6 and "iso-8859-6-i" as well, that is no longer true.
The single-byte decoder (decoder for single-byte encodings) is:
Let byte be the value at byte pointer.
If byte is the EOF byte, emit the EOF code point.
Increase the byte pointer by one.
If byte is in the range 0x00 to 0x7F, emit a code point whose value is byte.
Let code point be the index code point for byte − 0x80 in index single-byte.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
The single-byte encoder (encoder for single-byte encodings) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
Let pointer be the index pointer for code point in index single-byte.
If pointer is null, emit an encoder error.
Emit a byte whose value is pointer + 0x80.
The gb18030 flag flag is initially unset. It can only be set by the gb18030 decoder and gb18030 encoder.
The gbk first, gbk second, and gbk third, are all initially 0x00.
The gbk decoder (decoder for gbk) is:
Let byte be the value at byte pointer.
If byte is the EOF byte and gbk first, gbk second, and gbk third are 0x00, emit the EOF code point.
If byte is the EOF byte, and gbk first, gbk second, or gbk third is not 0x00, set gbk first, gbk second, and gbk third to 0x00, and emit a decoder error.
Increase the byte pointer by one.
If gbk third is not 0x00, run these substeps:
Let code point be null.
If byte is in the range 0x30 to 0x39, set code point to the index gb18030 code point for (((gbk first − 0x81) × 10 + gbk second − 0x30) × 126 + gbk third − 0x81) × 10 + byte − 0x30.
Set gbk first, gbk second, and gbk third to 0x00.
If code point is null, decrease the byte pointer by three and emit a decoder error.
Emit a code point whose value is code point.
If gbk second is not 0x00, run these substeps:
If byte is in the range 0x81 to 0xFE, set gbk third to byte and continue.
Decrease the byte pointer by two, set gbk first and gbk second to 0x00, and emit a decoder error.
If gbk first is not 0x00, run these substeps:
If byte is in the range 0x30 to 0x39 and the gb18030 flag is set, set gbk second to byte and continue.
Let lead be gbk first, let pointer be null, and set gbk first to 0x00.
Let offset be 0x40 if byte is less than 0x7F and 0x41 otherwise.
If byte is in the range 0x40 to 0x7E or 0x80 to 0xFE, set pointer to (lead − 0x81) × 190 + (byte − offset).
Let code point be null if pointer is null and the index code point for pointer in index gbk otherwise.
If pointer is null, decrease the byte pointer by one.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
If byte is in the range 0x00 to 0x7F, emit a code point whose value is byte.
If byte is 0x80, emit code point U+20AC.
If byte is in the range 0x81 to 0xFE, set gbk first to byte and continue.
Emit a decoder error.
The gbk encoder (encoder for gbk) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
Let pointer be the index pointer for code point in index gbk.
If pointer is not null, run these substeps:
Let lead be pointer / 190 + 0x81.
Let trail be pointer % 190.
Let offset be 0x40 if trail is less than 0x3F and 0x41 otherwise.
Emit two bytes whose values are lead and trail + offset.
If pointer is null and the gb18030 flag is unset, emit an encoder error.
Set pointer to the index gb18030 pointer for code point.
Let byte1 be pointer / 10 / 126 / 10.
Set pointer to pointer − byte1 × 10 × 126 × 10.
Let byte2 be pointer / 10 / 126.
Set pointer to pointer − byte2 × 10 × 126.
Let byte3 be pointer / 10.
Let byte4 be pointer − byte3 × 10.
Emit four bytes whose values are byte1 + 0x81, byte2 + 0x30, byte3 + 0x81, byte4 + 0x30.
The gb18030 decoder (decoder for gb18030) is the gbk decoder with the gb18030 flag set.
The gb18030 encoder (encoder for gb18030) is the gbk encoder with the gb18030 flag set.
The hz-gb-2312 flag is initially unset. The hz-gb-2312 lead is initially 0x00.
The hz-gb-2312 decoder (decoder for hz-gb-2312) is:
Let byte be the value at byte pointer.
If byte is the EOF byte and hz-gb-2312 lead is 0x00, emit the EOF code point.
If byte is the EOF byte and hz-gb-2312 lead is not 0x00, set hz-gb-2312 lead to 0x00 and emit a decoder error.
Increase the byte pointer by one.
If hz-gb-2312 lead is 0x7E, set hz-gb-2312 lead to 0x00, and based on byte:
Set the hz-gb-2312 flag and continue.
Unset the hz-gb-2312 flag and continue.
Emit code point U+007E.
Continue.
Decrease the byte pointer by one and emit a decoder error.
If hz-gb-2312 lead is not 0x00, let lead be hz-gb-2312 lead, set hz-gb-2312 lead to 0x00, and then run these substeps:
If byte is in the range 0x21 to 0x7E, let code point be the index code point for (lead − 1) × 190 + (byte + 0x3F) in index gbk.
If byte is 0x0A, unset the hz-gb-2312 flag.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
If byte is 0x7E, set hz-gb-2312 lead to 0x7E and continue.
If the hz-gb-2312 flag is set:
If byte is in the range 0x20 to 0x7F, set hz-gb-2312 lead to byte and continue.
If byte is 0x0A, unset the hz-gb-2312 flag.
Emit a decoder error.
If byte is in the range 0x00 to 0x7F, emit a code point whose value is byte.
Emit a decoder error.
The hz-gb-2312 encoder (encoder for hz-gb-2312) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F and the hz-gb-2312 flag is set, decrease the code point pointer by one, unset the hz-gb-2312 flag, and emit two bytes 0x7E 0x7D.
If code point is 0x007E, emit two bytes 0x7E 0x7E.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
Let pointer be the index pointer for code point in index gbk.
If pointer is null, emit an encoder error.
If the hz-gb-2312 flag is unset, decrease the code point pointer by one, set the hz-gb-2312 flag, and emit two bytes 0x7E 0x7B.
Let lead be pointer / 190 + 1.
Let trail be pointer % 190 − 0x3F.
If either lead or trail is less than 0x21, emit an encoder error.
Emit two bytes whose values are lead and trail.
The big5 lead is initially 0x00.
The big5 decoder (decoder for big5) is:
Let byte be the value at byte pointer.
If byte is the EOF byte and big5 lead is 0x00, emit the EOF code point.
If byte is the EOF byte and big5 lead is not 0x00, set big5 lead to 0x00 and emit a decoder error.
Increase the byte pointer by one.
If big5 lead is not 0x00, let lead be big5 lead, let pointer be null, set big5 lead to 0x00, and then run these substeps:
Let offset be 0x40 if byte is less than 0x7F and 0x62 otherwise.
If byte is in the range 0x40 to 0x7E or 0xA1 to 0xFE, set pointer to (lead − 0x81) × 157 + (byte − offset).
If there is a row in the table below whose first column is pointer, emit the two code points listed in its second column (the third column is irrelevant):
| Pointer | Code points | Notes |
|---|---|---|
| 1133 | U+00CA U+0304 | Ê̄ (LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND MACRON) |
| 1135 | U+00CA U+030C | Ê̌ (LATIN SMALL LETTER E WITH CIRCUMFLEX AND MACRON) |
| 1164 | U+00EA U+0304 | ê̄ (LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND CARON) |
| 1166 | U+00EA U+030C | ê̌ (LATIN SMALL LETTER E WITH CIRCUMFLEX AND CARON) |
Since indexes are limited to single code points this table is used for these pointers.
Let code point be null if pointer is null and the index code point for pointer in index big5 otherwise.
If pointer is null, decrease the byte pointer by one.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
If byte is in the range 0x00 to 0x7F, emit a code point whose value is byte.
If byte is in the range 0x81 to 0xFE, set big5 lead to byte and continue.
Emit a decoder error.
The big5 encoder (encoder for big5) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
Let pointer be the index pointer for code point in index big5.
If pointer is null, emit an encoder error.
Let lead be pointer / 157 + 0x81.
If lead is less than 0xA1, emit an encoder error.
Avoid emitting Hong Kong Supplementary Character Set extensions literally.
Let trail be pointer % 157.
Let offset be 0x40 if trail is less than 0x3F and 0x62 otherwise.
Emit two bytes whose values are lead and trail + offset.
The euc-jp first and euc-jp second are 0x00.
The euc-jp decoder (decoder for euc-jp) is:
Let byte be the value at byte pointer.
If byte is the EOF byte and euc-jp first and euc-jp second are 0x00, emit the EOF code point.
If byte is the EOF byte and either euc-jp first or euc-jp second is not 0x00, set euc-jp first and euc-jp second to 0x00, and emit a decoder error.
Increase the byte pointer by one.
If euc-jp second is not 0x00, let lead be euc-jp second, set euc-jp second to 0x00 and run these substeps:
Let code point be null.
If lead and byte are both in the range 0xA1 to 0xFE, set code point to the index code point for (lead − 0xA1) × 94 + byte − 0xA1 in index jis0212.
If byte is not in the range 0xA1 to 0xFE, decrease byte pointer by one.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
If euc-jp first is 0x8E and byte is in the range 0xA1 to 0xDF, set euc-jp first to 0x00 and emit a code point whose value is 0xFF61 + byte − 0xA1.
If euc-jp first is 0x8F and byte is in the range 0xA1 to 0xFE, set euc-jp first to 0x00, euc-jp second to byte, and continue.
If euc-jp first is not 0x00, let lead be euc-jp first, set euc-jp first to 0x00, and run these substeps:
Let code point be null.
If lead and byte are both in the range 0xA1 to 0xFE, set code point to the index code point for (lead − 0xA1) × 94 + byte − 0xA1 in index jis0208.
If byte is not in the range 0xA1 to 0xFE, decrease byte pointer by one.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
If byte is in the range 0x00 to 0x7F, emit a code point whose value is byte.
If byte is 0x8E, 0x8F, or in the range 0xA1 to 0xFE, set euc-jp first to byte and continue.
Emit a decoder error.
The euc-jp encoder (encoder for euc-jp) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
If code point is U+00A5, emit byte 0x5C.
If code point is U+203E, emit byte 0x7E.
If code point is in the range U+FF61 to U+FF9F, emit two bytes whose values are 0x8E and code point − 0xFF61 + 0xA1.
Let pointer be the index pointer for code point in index jis0208.
If pointer is null, emit an encoder error.
Let lead be pointer / 94 + 0xA1.
Let trail be pointer % 94 + 0xA1.
Emit two bytes whose values are lead and trail.
The index jis0212 is not used by the euc-jp encoder due to lack of widespread support.
The iso-2022-jp state is initially ASCII state.
The iso-2022-jp jis0212 flag is initially unset.
The iso-2022-jp lead is initially 0x00.
The iso-2022-jp decoder (decoder for iso-2022-jp) is:
Let byte be the value at byte pointer.
If byte is not the EOF byte, increase the byte pointer by one.
Based on iso-2022-jp state:
Based on byte:
Set iso-2022-jp state to escape start state and continue.
Emit a code point whose value is byte.
Emit the EOF code point.
Emit a decoder error.
If byte is either 0x24 or 0x28, set iso-2022-jp lead to byte, iso-2022-jp state to escape middle state, and continue.
If byte is not the EOF byte, decrease the byte pointer by one.
Set iso-2022-jp state to ASCII state and emit a decoder error.
Let lead be iso-2022-jp lead and set iso-2022-jp lead to 0x00.
If lead is 0x24 and byte is either 0x40 or 0x42, unset the iso-2022-jp jis0212 flag, set iso-2022-jp state to lead state, and continue.
If lead is 0x24 and byte is 0x28, set iso-2022-jp state to escape final state and continue.
If lead is 0x28 and byte is either 0x42 or 0x4A, set iso-2022-jp state to ASCII state and continue.
If lead is 0x28 and byte is 0x49, set iso-2022-jp state to Katakana state and continue.
If byte is the EOF byte, decrease byte pointer by one, and decrease it by two otherwise.
Set iso-2022-jp state to ASCII state and emit a decoder error.
If byte is 0x44, set the iso-2022-jp jis0212 flag, set iso-2022-jp state to lead state, and continue.
If byte is the EOF byte, decrease byte pointer by two, and decrease it by three otherwise.
Set iso-2022-jp state to ASCII state and emit a decoder error.
Based on byte:
Set iso-2022-jp state to ASCII state and emit code point U+000A.
Set iso-2022-jp state to escape start state and continue.
Emit the EOF code point.
Set iso-2022-jp lead to byte, iso-2022-jp state to trail state, and continue.
Set the iso-2022-jp state to lead state.
If byte is the EOF byte, emit a decoder error.
Let code point be null and let pointer be (iso-2022-jp lead − 0x21) × 94 + byte − 0x21.
If iso-2022-jp lead and byte are both in the range 0x21 to 0x7E, set code point to the index code point for pointer in index jis0208 if the iso-2022-jp jis0212 flag is unset and in index jis0212 otherwise.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
Based on byte:
Set iso-2022-jp state to escape start state and continue.
Emit a code point whose value is 0xFF61 + byte − 0x21.
Emit the EOF code point.
Emit a decoder error.
The iso-2022-jp encoder (encoder for iso-2022-jp) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, or is U+00A5 or U+203E, and iso-2022-jp state is not ASCII state, decrease the code point pointer by one, set iso-2022-jp state to ASCII state, and emit three bytes 0x1B 0x28 0x42.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
If code point is U+00A5, emit byte 0x5C.
If code point is U+203E, emit byte 0x7E.
If code point is in the range U+FF61 to U+FF9F and iso-2022-jp state is not Katakana state, decrease the code point pointer by one, set iso-2022-jp state to Katakana state, and emit three bytes 0x1B 0x28 0x49.
If code point is in the range U+FF61 to U+FF9F, emit a byte whose value is code point − 0xFF61 + 0x21.
Let pointer be the index pointer for code point in index jis0208.
If pointer is null, emit an encoder error.
If iso-2022-jp state is not lead state, decrease the code point pointer by one, set iso-2022-jp state to lead state, and emit three bytes 0x1B 0x24 0x42.
Let lead be pointer / 94 + 0x21.
Let trail be pointer % 94 + 0x21.
Emit two bytes whose values are lead and trail.
The index jis0212 is not used by the iso-2022-jp encoder due to lack of widespread support.
The shift_jis lead is initially 0x00.
The shift_jis decoder (decoder for shift_jis) is:
Let byte be the value at byte pointer.
If byte is the EOF byte and shift_jis lead is 0x00, emit the EOF code point.
If byte is the EOF byte, shift_jis lead is not 0x00, set shift_jis lead to 0x00 and emit a decoder error.
Increase the byte pointer by one.
If shift_jis lead is not 0x00, let lead be shift_jis lead, let pointer be null, set shift_jis lead to 0x00, and then run these substeps:
Let offset be 0x40 if byte is less than 0x7F and 0x41 otherwise.
Let lead offset be 0x81 if lead is less than 0xA0 and 0xC1 otherwise.
If byte is in the range 0x40 to 0x7E or 0x80 to 0xFC, set pointer to (lead − lead offset) × 188 + byte − offset.
Let code point be null if pointer is null and the index code point for pointer in index jis0208 otherwise.
If pointer is null, decrease the byte pointer by one.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
If byte is in the range 0x00 to 0x80, emit a code point whose value is byte.
If byte is in the range 0xA1 to 0xDF, emit a code point whose value is 0xFF61 + byte − 0xA1.
If byte is in the range 0x81 to 0x9F or 0xE0 to 0xFC, set shift_jis lead to byte and continue.
Emit a decoder error.
The shift_jis encoder (encoder for shift_jis) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+0080, emit a byte whose value is code point.
If code point is U+00A5, emit byte 0x5C.
If code point is U+203E, emit byte 0x7E.
If code point is in the range U+FF61 to U+FF9F, emit a byte whose value is code point − 0xFF61 + 0xA1.
Let pointer be the index pointer for code point in index jis0208.
If pointer is null, emit an encoder error.
Let lead be pointer / 188.
Let lead offset be 0x81 if lead is less than 0x1F and 0xC1 otherwise.
Let trail be pointer % 188.
Let offset be 0x40 if trail is less than 0x3F and 0x41 otherwise.
Emit two bytes whose values are lead + lead offset and trail + offset.
The euc-kr lead is initially 0x00.
The euc-kr decoder (decoder for euc-kr) is:
Let byte be the value at byte pointer.
If byte is the EOF byte and euc-kr lead is 0x00, emit the EOF code point.
If byte is the EOF byte and euc-kr lead is not 0x00, set euc-kr lead to 0x00 and emit a decoder error.
Increase the byte pointer by one.
If euc-kr lead is not 0x00, let lead be euc-kr lead, let pointer be null, set euc-kr lead to 0x00, and then run these substeps:
If lead is in the range 0x81 to 0xC6, let temp be (26 + 26 + 126) × (lead − 0x81), and then set pointer to the result of the equation below, depending on byte:
temp + byte − 0x41
temp + 26 + byte − 0x61
temp + 26 + 26 + byte − 0x81
If lead is in the range 0xC7 to 0xFE and byte is in the range 0xA1 to 0xFE, set pointer to (26 + 26 + 126) × (0xC7 − 0x81) + (lead − 0xC7) × 94 + (byte − 0xA1).
Let code point be null if pointer is null and the index code point for pointer in index euc-kr otherwise.
If pointer is null, decrease the byte pointer by one.
If code point is null, emit a decoder error.
Emit a code point whose value is code point.
If byte is in the range 0x00 to 0x7F, emit a code point whose value is byte.
If byte is in the range 0x81 to 0xFE, set euc-kr lead to byte and continue.
Emit a decoder error.
The euc-kr encoder (encoder for euc-kr) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
Let pointer be the index pointer for code point in index euc-kr.
If pointer is null, emit an encoder error.
If pointer is less than (26 + 26 + 126) × (0xC7 − 0x81), run these substeps:
Let lead be pointer / (26 + 26 + 126) + 0x81.
Let trail be pointer % (26 + 26 + 126).
Let offset be 0x41 if trail is less than 26, 0x47 if trail is less than 26 + 26, and 0x4D otherwise.
Emit two bytes whose values are lead and trail + offset.
Set pointer to pointer − (26 + 26 + 126) × (0xC7 − 0x81).
Let lead be pointer / 94 + 0xC7.
Let trail be pointer % 94 + 0xA1.
Emit two bytes whose values are lead and trail.
This encoding is considered for removal from the platform.
The iso-2022-kr state is initially ASCII state.
The iso-2022-kr lead is initially 0x00.
The iso-2022-kr decoder (decoder for iso-2022-kr) is:
Let byte be the value at byte pointer.
If byte is not the EOF byte, increase the byte pointer by one.
Based on iso-2022-kr state:
Based on byte:
Set iso-2022-kr state to lead state and continue.
Continue.
Set iso-2022-kr state to escape start state and continue.
Emit a code point whose value is byte.
Emit the EOF code point.
Emit a decoder error.
If byte is 0x24, set iso-2022-kr state to escape middle state and continue.
If byte is not the EOF byte, decrease the byte pointer by one.
Set iso-2022-kr state to ASCII state and emit a decoder error.
If byte is 0x29, set iso-2022-kr state to escape end state and continue.
If byte is the EOF byte, decrease the byte pointer by one, and decrease it by two otherwise.
Set iso-2022-kr state to ASCII state and emit a decoder error.
If byte is 0x43, set iso-2022-kr state to ASCII state and continue.
If byte is the EOF byte, decrease the byte pointer by two, and decrease it by three otherwise.
Set iso-2022-kr state to ASCII state and emit a decoder error.
Based on byte:
Set iso-2022-kr state to ASCII state and emit code point U+000A.
Continue.
Set iso-2022-kr state to ASCII state and continue.
Emit the EOF code point.
Set iso-2022-kr lead to byte, set iso-2022-kr state to trail state, and continue.
Set the iso-2022-kr state to lead state.
If byte is the EOF byte, emit a decoder error.
Let code point be null.
If iso-2022-kr lead is in the range 0x21 to 0x46 and byte is in the range 0x21 to 0x7E, set code point to the index code point for (26 + 26 + 126) × (iso-2022-kr lead − 1) + 26 + 26 + byte − 1 in index euc-kr.
If iso-2022-kr lead is in the range 0x47 to 0x7E and byte is in the range 0x21 to 0x7E, set code point to the index code point for (26 + 26 + 126) × (0xC7 − 0x81) + (iso-2022-kr lead − 0x47) × 94 + (byte − 0x21) in index euc-kr.
If code point is not null, emit code point.
Emit a decoder error.
The iso-2022-kr initialization flag is initially unset.
The iso-2022-kr encoder (encoder for iso-2022-kr) is:
Let code point be the value at code point pointer.
If code point is the EOF code point and iso-2022-kr state is not ASCII state, set iso-2022-kr state to ASCII state and emit byte 0x0F.
If code point is the EOF code point, emit the EOF byte.
If the iso-2022-kr initialization flag is unset, set the iso-2022-kr initialization flag and emit four bytes 0x1B 0x24 0x29 0x43.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F and iso-2022-kr state is not ASCII state, decrease the code point pointer by one, set iso-2022-kr state to ASCII state, and emit byte 0x0F.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
Let pointer be the index pointer for code point in index euc-kr.
If pointer is null, emit an encoder error.
If iso-2022-kr state is not lead state, decrease the code point pointer by one, set iso-2022-kr state to lead state, and emit byte 0x0E.
If pointer is less than (26 + 26 + 126) × (0xC7 − 0x81), run these substeps:
Let lead be pointer / (26 + 26 + 126) + 1.
Let trail be pointer % (26 + 26 + 126) − 26 − 26 + 1.
If either lead or trail is less than 0x21, emit an encoder error.
Emit two bytes whose values are lead and trail.
Set pointer to pointer − (26 + 26 + 126) × (0xC7 − 0x81).
Let lead be pointer / 94 + 0x47.
Let trail be pointer % 94 + 0x21.
Emit two bytes whose values are lead and trail.
The replacement encoding exists to prevent certain attacks that abuse a mismatch between encodings supported on the server and the client.
The replacement decoder (decoder for replacement) is to emit a decoder error followed by an EOF code point.
The replacement encoder (encoder for replacement) is the utf-8 encoder.
In violation of the Unicode standard, checking for a byte order mark happens before an encoding to decode a byte stream is chosen, as seen in the decode algorithm.
The utf-16 lead byte and utf-16 lead surrogate are initially null and the utf-16be flag is initially unset.
The utf-16 decoder is:
Let byte be the value at byte pointer.
If byte is the EOF byte and utf-16 lead byte and utf-16 lead surrogate are null, emit the EOF code point.
If byte is the EOF byte and either utf-16 lead byte or utf-16 lead surrogate is not null, set utf-16 lead byte and utf-16 lead surrogate to null, and emit a decoder error.
Increase the byte pointer by one.
If utf-16 lead byte is null, set utf-16 lead byte to byte and continue.
Let code point be the result of:
(utf-16 lead byte << 8) + byte.
(byte << 8) + utf-16 lead byte.
Then set utf-16 lead byte to null.
If utf-16 lead surrogate is not null, let lead surrogate be utf-16 lead surrogate, set utf-16 lead surrogate to null, and then run these substeps:
If code point is in the range U+DC00 to U+DFFF, emit a code point whose value is 0x10000 + (lead surrogate − 0xD800) × 0x400 + (code point − 0xDC00).
Decrease the byte pointer by two and emit a decoder error.
If code point is in the range U+D800 to U+DBFF, set utf-16 lead surrogate to code point and continue.
If code point is in the range U+DC00 to U+DFFF, emit a decoder error.
Emit code point code point.
To convert a code unit to bytes run these steps:
Let byte1 be code unit >> 8.
Let byte2 be code unit & 0x00FF.
Then return the bytes in order:
byte1, then byte2.
byte2, then byte1.
The utf-16 encoder is:
Let code point be the value at code point pointer.
If code point is in the range 0xD800 to 0xDFFF, emit an encoder error.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range 0x00 to 0xFFFF, emit the sequence resulting of converting code point to bytes.
Let lead be (code point − 0x10000) / 0x400 + 0xD800, converted to bytes.
Let trail be (code point − 0x10000) % 0x400 + 0xDC00, converted to bytes.
Emit a sequence of bytes that consists of lead followed by trail.
The utf-16be decoder (decoder for utf-16be) is the utf-16 decoder with the utf-16be flag set.
The utf-16be encoder (encoder for utf-16be) is the utf-16 encoder with the utf-16be flag set.
In violation of the Unicode standard,
"utf-16" is a label for
utf-16le rather than its own standalone encoding.
The utf-16le decoder (decoder for utf-16le) is the utf-16 decoder.
The utf-16le encoder (encoder for utf-16le) is the utf-16 encoder.
While technically this is a single-byte encoding, it is defined separately as it can be implemented algorithmically.
The x-user-defined decoder (decoder for x-user-defined) is:
Let byte be the value at byte pointer.
If byte is the EOF byte, emit the EOF code point.
Increase the byte pointer by one.
If byte is in the range 0x00 to 0x7F, emit a code point whose value is byte.
Emit a code point whose value is 0xF780 + byte − 0x80.
The x-user-defined encoder (encoder for x-user-defined) is:
Let code point be the value at code point pointer.
If code point is the EOF code point, emit the EOF byte.
Increase the code point pointer by one.
If code point is in the range U+0000 to U+007F, emit a byte whose value is code point.
If code point is in the range U+F780 to U+F7FF, emit a byte whose value is code point − 0xF780 + 0x80.
Emit an encoder error.
There have been a lot of people that have helped make encodings more interoperable over the years and thereby furthered the goals of this standard. Likewise many people have helped making this standard what it is today.
Ideally they are all listed here so please contact the editor with any omissions.
With that, many thanks to Alan Chaney, Ben Noordhuis, Boris Zbarsky, Cameron McCormack, Charles McCathieNeville, David Carlisle, Doug Ewell, Erik van der Poel, 譚永鋒 (Frank Yung-Fong Tang), Glenn Maynard, Gordon P. Hemsley, Henri Sivonen, Ian Hickson, James Graham, John Tamplin, Joshua Bell, 신정식 (Jungshik Shin), 川幡太一 (Kawabata Taichi), Ken Lunde, Kenneth Russell, Leif Halvard Silli, Makoto Kato, Mark Callow, Mark Davis, Martin Dürst, Masatoshi Kimura, Ms2ger, Norbert Lindenberg, Øistein E. Andersen, Peter Krefting, Philip Jägenstedt, Philip Taylor, Robbert Broersma, Robert Mustacchi, Ryan Dahl, Shawn Steele, Simon Montagu, Simon Pieters, Simon Sapin, and 成瀬ゆい (Yui Naruse) for being awesome.