RFC 3629

UTF-8, a transformation format of ISO 10646

πŸ“… published November 2003, from ietf

RFC 3629 πŸŽ€ UTF-8, a transformation format of ISO 10646 ✨

Network Working Group 🌸 this one is from the IETF crew, so it's a real standards doc, not a vibe. Here's the deal:

  • Author: F. Yergeau, Alis Technologies πŸ’…
  • Date: November 2003 πŸ“…
  • Category: Standards Track πŸ‘‘
  • STD: 63
  • Obsoletes: 2279 (it replaces the old one, so no more RFC 2279 stans 😭)

Status of this Memo πŸ“œ

Okay so this doc is an Internet standards track protocol for the Internet community, and it's asking everyone to talk about it and send ideas for making it better πŸ—£οΈβœ¨. If you want to know where this protocol stands officially, go check the current "Internet Official Protocol Standards" (STD 1) πŸ”. And the good news is that distribution of this memo is unlimited, so share it with everyone bestie πŸ’–.

Copyright (C) The Internet Society (2003). All Rights Reserved. πŸ”’

Abstract 🌈

ISO/IEC 10646-1 defines a massive character set called the Universal Character Set (UCS), and it covers most of the world's writing systems 🌍🫢. The first encodings people came up with for UCS weren't compatible with a lot of the apps and protocols we actually use, which was a major problem 😩. So UTF-8 was developed, and that's what this memo is all about πŸ¦‹. Its superpower is that it keeps the full US-ASCII range intact, so file systems, parsers, and other software that depend on US-ASCII values keep working, and they stay totally chill about every other value 🧚. This memo obsoletes and replaces RFC 2279 πŸ’œ.

Table of Contents πŸ“š

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
   2.  Notational conventions . . . . . . . . . . . . . . . . . . . .  3
   3.  UTF-8 definition . . . . . . . . . . . . . . . . . . . . . . .  4
   4.  Syntax of UTF-8 Byte Sequences . . . . . . . . . . . . . . . .  5
   5.  Versions of the standards  . . . . . . . . . . . . . . . . . .  6
   6.  Byte order mark (BOM)  . . . . . . . . . . . . . . . . . . . .  6
   7.  Examples . . . . . . . . . . . . . . . . . . . . . . . . . . .  8
   8.  MIME registration  . . . . . . . . . . . . . . . . . . . . . .  9
   9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 10
   10. Security Considerations  . . . . . . . . . . . . . . . . . . . 10
   11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 11
   12. Changes from RFC 2279  . . . . . . . . . . . . . . . . . . . . 11
   13. Normative References . . . . . . . . . . . . . . . . . . . . . 12
   14. Informative References . . . . . . . . . . . . . . . . . . . . 12
   15. URI's  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
   16. Intellectual Property Statement  . . . . . . . . . . . . . . . 13
   17. Author's Address . . . . . . . . . . . . . . . . . . . . . . . 13
   18. Full Copyright Statement . . . . . . . . . . . . . . . . . . . 14

1. Introduction ✨

So ISO/IEC 10646 [ISO.10646] is where the Universal Character Set (UCS) lives, and it covers most of the world's writing systems 🌏. The Unicode standard [UNICODE] has the exact same set of characters, but it also adds character properties and other app details that implementers absolutely need πŸ€“. Up until now, Unicode and ISO/IEC 10646 have been updating in lockstep, so the character repertoires and code point assignments have stayed in sync πŸ”„. The standards committees are committed to keeping that synchronism going, and honestly it's iconic of them πŸ’–.

ISO/IEC 10646 and Unicode define several encoding forms for their shared repertoire: UTF-8, UCS-2, UTF-16, UCS-4 and UTF-32 🧩. In any encoding form, each character gets represented as one or more encoding units. Every standard UCS encoding form besides UTF-8 has an encoding unit bigger than one octet, which makes them a pain to use in lots of current apps and protocols that assume 8 or even 7 bit characters 😀.

UTF-8, the star of this memo, has a one-octet encoding unit πŸ¦‹. It uses all the bits of an octet, but it keeps the full US-ASCII [US-ASCII] range intact 🫢. US-ASCII characters get encoded in one octet with the normal US-ASCII value, and any octet with that value can only stand for a US-ASCII character and nothing else πŸ’….

UTF-8 encodes UCS characters as a varying number of octets, and both the count and the value of each octet depend on the integer value that ISO/IEC 10646 assigns to the character πŸ”’. That integer goes by a few names: the character number, a.k.a. code position, code point, or Unicode scalar value 🏷️. This encoding form has the following characteristics (all values are in hexadecimal) 🌈:

  • Character numbers from U+0000 to U+007F (the US-ASCII repertoire) correspond to octets 00 to 7F (7 bit US-ASCII values). A direct result of this is that a plain ASCII string is also a valid UTF-8 string πŸ’–.
  • US-ASCII octet values do not appear otherwise in a UTF-8 encoded character stream. This gives compatibility with file systems or other software (e.g., the printf() function in C libraries) that parse based on US-ASCII values but stay transparent to other values 🧚.
  • Round-trip conversion is easy between UTF-8 and other encoding forms πŸ”.
  • The first octet of a multi-octet sequence tells you how many octets are in the sequence πŸ”’.
  • The octet values C0, C1, F5 to FF never appear 🚫.
  • Character boundaries are easily found from anywhere in an octet stream πŸ“.
  • The byte-value lexicographic sorting order of UTF-8 strings is the same as if they were ordered by character numbers. Of course this is of limited interest, since a sort order based on character numbers is almost never culturally valid πŸ™ˆ.
  • The Boyer-Moore fast search algorithm can be used with UTF-8 data πŸ”.
  • UTF-8 strings can be fairly reliably recognized as such by a simple algorithm. The probability that a string of characters in any other encoding looks like valid UTF-8 is low, and it keeps dropping as the string gets longer πŸ•΅οΈβ€β™€οΈ.

UTF-8 was devised in September 1992 by Ken Thompson, following design criteria from Rob Pike πŸ‘‘. The goal was a UCS transformation format that could be used in the Plan9 operating system in a non-disruptive way πŸ“. Thompson's design then got standardized through the X/Open Joint Internationalization Group XOJIG (see [FSS_UTF]) 🀝. Along the way it went by a few names: FSS-UTF (variant FSS/UTF), UTF-2, and finally UTF-8 🌸.

2. Notational conventions πŸ“

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] 🫢.

UCS characters are written with the U+HHHH notation, where HHHH is a string of 4 to 6 hexadecimal digits representing the character number in ISO/IEC 10646 πŸ”€.

3. UTF-8 definition πŸ’œ

UTF-8 is defined by the Unicode Standard [UNICODE]. You can also find descriptions and formulae in Annex D of ISO/IEC 10646-1 [ISO.10646] ✨.

In UTF-8, characters from the U+0000..U+10FFFF range (the UTF-16 accessible range) get encoded using sequences of 1 to 4 octets 🌈. A "sequence" of one only has one octet, and its higher-order bit is set to 0, so the other 7 bits are used to encode the character number 🧩. In a sequence of n octets, where n>1, the initial octet has its n higher-order bits set to 1, followed by a bit set to 0. The remaining bit(s) of that octet hold bits from the character number πŸ”’. Each following octet has its higher-order bit set to 1 and the next bit set to 0, which leaves 6 bits in each one to hold bits from the character being encoded πŸ’….

The table below sums up the format of these octet types. The letter x marks the bits available for encoding bits of the character number πŸŽ€.

   Char. number range  |        UTF-8 octet sequence
      (hexadecimal)    |              (binary)
   --------------------+---------------------------------------------
   0000 0000-0000 007F | 0xxxxxxx
   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Here's how to encode a character to UTF-8, step by step πŸͺ„:

  1. Figure out how many octets you need from the character number and the first column of the table above. It's really important to note that the rows of the table are mutually exclusive, which means there's only one valid way to encode a given character 🚦.
  2. Set up the high-order bits of the octets according to the second column of the table 🧱.
  3. Fill in the bits marked x with the bits of the character number, written in binary. Start by putting the lowest-order bit of the character number into the lowest-order position of the last octet of the sequence. Then put the next higher-order bit into the next higher-order position of that octet, and keep going. Once the x bits of the last octet are full, move on to the next-to-last octet, then the one before it, and so on until every x bit is filled 🧩✨.

The definition of UTF-8 forbids encoding character numbers between U+D800 and U+DFFF. Those are reserved for use with the UTF-16 encoding form (as surrogate pairs), and they don't directly represent characters 🚫. When you're encoding UTF-8 from UTF-16 data, you have to decode the UTF-16 data first to get the character numbers, and then encode those in UTF-8 as described above πŸ”„. This is different from CESU-8 [CESU-8], which is a UTF-8-like encoding that is not meant for use on the Internet πŸ™…β€β™€οΈ. CESU-8 works similarly to UTF-8, but it encodes the UTF-16 code values (16-bit quantities) instead of the character number (code point). That leads to different results for character numbers above 0xFFFF, and the CESU-8 encoding of those characters is not valid UTF-8 πŸ’€.

Here's how to decode a UTF-8 character πŸ”:

  1. Start with a binary number where all bits are set to 0. You might need up to 21 bits πŸ”’.
  2. Work out which bits encode the character number, using the number of octets in the sequence and the second column of the table above (the bits marked x) πŸ•΅οΈβ€β™€οΈ.
  3. Spread the bits from the sequence across the binary number. Start with the lower-order bits from the last octet of the sequence and keep moving left until there are no x bits left. At that point the binary number is equal to the character number πŸŽ‰.

Implementations of the decoding algorithm above MUST protect against decoding invalid sequences. Let me be super clear about why, bestie 😭: a naive implementation might decode the overlong UTF-8 sequence C0 80 into the character U+0000, or decode the surrogate pair ED A1 8C ED BE B4 into U+233B4 πŸ’€. Decoding invalid sequences can have security consequences or cause other problems 🚨. See Security Considerations (Section 10) below πŸ”.

4. Syntax of UTF-8 Byte Sequences ✨

okay so this is the part where implementors get their ABNF, bestie πŸŽ€ the spec gives us a grammar for UTF-8 so you can check bytes in your own code. ngl this is the most useful section for anyone writing a parser πŸ’…

For the convenience of implementors using ABNF, a definition of UTF-8 in ABNF syntax is given here.

A UTF-8 string is a sequence of octets representing a sequence of UCS characters. An octet sequence is valid UTF-8 only if it matches the following syntax, which is derived from the rules for encoding UTF-8 and is expressed in the ABNF of [RFC2234].

UTF8-octets = *( UTF8-char )
UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
UTF8-1      = %x00-7F
UTF8-2      = %xC2-DF UTF8-tail
UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
              %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
              %xF4 %x80-8F 2( UTF8-tail )
UTF8-tail   = %x80-BF
NOTE -- The authoritative definition of UTF-8 is in [UNICODE]. This grammar is believed to describe the same thing Unicode describes, but does not claim to be authoritative. Implementors are urged to rely on the authoritative source, rather than on this ABNF.

5. Versions of the standards 🌈

okay, the standards keep getting updated πŸ₯Ή ISO/IEC 10646 gets new amendments and extra parts over time, and the Unicode standard gets new versions too. each new version obsoletes and replaces the one before it, BUT the software and especially the data out there doesn't get updated instantly. it's giving "the old stuff is still floating around" 😭

mostly the changes are just adding new characters, which doesn't cause much drama with old data. the big plot twist: in 1996, Amendment 5 to the 1993 edition of ISO/IEC 10646 and Unicode 2.0 moved and expanded the Korean Hangul block. so any old data with Hangul characters became invalid under the new version. Unicode 2.0 had the same difference from Unicode 1.1. the reason they got away with it was that there were no major implementations and not much data with Hangul in it. this is the infamous "Korean mess" πŸ’€ and the committees have pinky-promised to never, ever do that kind of incompatible change again (see Unicode Consortium Policies [1]).

new versions, especially incompatible ones, affect MIME charset labels, which get discussed in MIME registration (Section 8). more on that soon πŸ¦‹


6. Byte order mark (BOM) 🧚

so the UCS character U+FEFF "ZERO WIDTH NO-BREAK SPACE" is also called "BYTE ORDER MARK" (or "BOM" for short) πŸ“ it can totally be used as a real zero width no-break space inside your text. BUT the name hints at a second job: putting a U+FEFF at the very start of a stream as a "signature". a receiver can see that first character and go "ooh, this is a stream of UCS characters," figure out which UCS encoding is involved, and, for encodings with multi-octet units, work out the byte order. for UTF-8, which has single-octet units, that last part is useless, so the BOM will always show up as the octet sequence EF BB BF πŸ’œ

now the important bit: a U+FEFF anywhere that isn't the start of a stream MUST be read as a zero width non-breaking space, and it MUST NOT be read as a signature 🚫 when it IS read as a signature, Unicode suggests that the initial U+FEFF may be stripped before processing. stripping is sometimes necessary (like when you concatenate two strings, otherwise you could end up with a stray "ZERO WIDTH NO-BREAK SPACE" at the join πŸ™ˆ). but it could mess with an external process at another layer, like a digital signature or a character count, that relies on every character being there. so it is RECOMMENDED to avoid stripping an initial U+FEFF that's being used as a signature without a good reason, to ignore it instead of stripping when that's appropriate (like for display), and to only strip it when it's really necessary ✨

a U+FEFF at the first position MAY be read as a zero width non-breaking space, and it's not always a signature. to fix that confusion, Unicode 3.2 added a new character, U+2060 "WORD JOINER". it has exactly the same semantics and usage as U+FEFF, except for the signature function, and Unicode strongly recommends using it exclusively for word-joining. if everyone follows that, it becomes almost certain that any initial U+FEFF is a signature and not an intended "ZERO WIDTH NO-BREAK SPACE" 🌸

in the meantime the uncertainty is still there, and it can affect Internet protocols. protocol specs MAY restrict the use of U+FEFF as a signature to reduce or get rid of the possible bad effects. to balance the good (less uncertainty) against the bad (losing the signature function), there are a few cases to think about:

  • A protocol SHOULD forbid use of U+FEFF as a signature for those textual protocol elements that the protocol mandates to be always UTF-8, since the signature is totally useless in those cases.
  • A protocol SHOULD also forbid use of U+FEFF as a signature for those textual protocol elements for which the protocol provides character encoding identification mechanisms, when it's expected that implementations will always be able to use those mechanisms properly. this happens when the protocol elements are tightly controlled by the implementation from creation to their (properly labeled) transmission.
  • A protocol SHOULD NOT forbid use of U+FEFF as a signature for those textual protocol elements for which the protocol does NOT provide character encoding identification mechanisms, when a ban would be unenforceable, or when implementations are not expected to always use the mechanisms properly. the last two cases are likely with bigger protocol elements like MIME entities, especially when implementations get them from file systems, from protocols with no encoding identification for payloads (like FTP), or from other protocols that don't guarantee proper character encoding identification (like HTTP) πŸ₯Ί

so when a protocol forbids U+FEFF as a signature for a certain protocol element, any initial U+FEFF in that element MUST be read as a "ZERO WIDTH NO-BREAK SPACE" πŸ™…β€β™€οΈ and when a protocol does NOT forbid it for an element, implementations SHOULD be ready to handle a signature there and react appropriately: use the signature to identify the character encoding if needed, and strip or ignore it as appropriate πŸ’–


7. Examples πŸ“

here's how it looks in actual bytes, bestie, let's gooo πŸ¦‹

The character sequence U+0041 U+2262 U+0391 U+002E "A<NOT IDENTICAL TO><ALPHA>." is encoded in UTF-8 as follows:

    --+--------+-----+--
    41 E2 89 A2 CE 91 2E
    --+--------+-----+--

The character sequence U+D55C U+AD6D U+C5B4 (Korean "hangugeo", meaning "the Korean language") is encoded in UTF-8 as follows:

    --------+--------+--------
    ED 95 9C EA B5 AD EC 96 B4
    --------+--------+--------

The character sequence U+65E5 U+672C U+8A9E (Japanese "nihongo", meaning "the Japanese language") is encoded in UTF-8 as follows:

    --------+--------+--------
    E6 97 A5 E6 9C AC E8 AA 9E
    --------+--------+--------

The character U+233B4 (a Chinese character meaning 'stump of tree'), prepended with a UTF-8 BOM, is encoded in UTF-8 as follows:

    --------+-----------
    EF BB BF F0 A3 8E B4
    --------+-----------

8. MIME registration πŸŽ€

this memo is the basis for registering the MIME charset parameter for UTF-8, following [RFC2978]. the charset parameter value is "UTF-8" πŸ’… that label covers text made of characters from the ISO/IEC 10646 repertoire, including all amendments up to at least amendment 5 of the 1993 edition (the Korean block), encoded into octets with the scheme we outlined above. UTF-8 works for MIME content types under the "text" top-level type.

it's kind of a big deal that the label "UTF-8" has no version number, and it refers to ISO/IEC 10646 generically. that's on purpose, and here's the tea 🫢

a MIME charset label is only supposed to give the info needed to turn the bytes on the wire into characters, nothing more (see [RFC2045], section 2.2). as long as a character set doesn't change incompatibly, version numbers are pointless, because knowing the tag doesn't help you with newly assigned characters you might get anyway. the tag doesn't teach you anything about those new characters.

so as long as the standards evolve compatibly, having version labels is only an apparent advantage. the real downside: when an older app gets data with a newer label it doesn't know, it might not recognize the label and be totally unable to deal with the data. a generic, known label would have triggered mostly correct processing, because the data probably doesn't contain any new characters anyway 😭

now, the "Korean mess" (ISO/IEC 10646 amendment 5) IS an incompatible change, which in principle goes against using a version-independent MIME charset label like we just talked about. BUT the compatibility problem only shows up with data containing Korean Hangul characters encoded per Unicode 1.1 (or the equivalent ISO/IEC 10646 before amendment 5), and arguably there's no such data left to worry about. that's exactly why the incompatible change was considered acceptable πŸ™ˆ

so in practice, a version-independent label is justified, as long as the label is understood to mean all versions after Amendment 5, and as long as no incompatible change actually happens. if an incompatible change does happen in a later version of ISO/IEC 10646, the MIME charset label defined here will stay aligned with the previous version, unless and until the IETF specifically decides otherwise πŸ‘‘


9. IANA Considerations 🌈

last one for this part, and it's a quick win ✨ the entry for UTF-8 in the IANA charset registry has been updated to point to this memo πŸ¦‹

10. Security Considerations πŸ”

Bestie, this section is seriously important 😭 If you're writing a UTF-8 implementation, you need to think hard about how you handle illegal UTF-8 sequences. An attacker could totally exploit a careless parser by sending it an octet sequence that the UTF-8 syntax doesn't allow.

A particularly sneaky version of this attack goes after a parser that does its security checks on the UTF-8 encoded form of the input, but then interprets some illegal octet sequences as real characters. For example, a parser might block the NUL character when it's written as the single octet 00, but accidentally let through the illegal two-octet sequence C0 80 and read it as NUL πŸ’€. Another example is a parser that blocks the octet sequence 2F 2E 2E 2F (/../) but still allows the illegal octet sequence 2F C0 AE 2E 2F. This last one was actually used in a widespread virus that attacked Web servers in 2001, so yes, the threat is very real. 🚨

Encoding to UTF-8 has its own risk too. The ISO/IEC 10646 description of UTF-8 allows character numbers up to U+7FFFFFFF, which can produce sequences of up to 6 bytes. So there's a risk of buffer overflow if the range of character numbers isn't explicitly limited to U+10FFFF, or if buffer sizing doesn't account for 5- and 6-byte sequences. Make sure you're limiting it! 🧱

Here's another one that's giving "same thing, different bytes" energy. Several character encodings, UTF-8 included, can represent the "same thing" (as far as a user can tell) using several distinct character sequences. For example, an e with an acute accent can be the precomposed U+00E9 (E ACUTE) character, or the canonically equivalent sequence U+0065 U+0301 (E + COMBINING ACUTE). UTF-8 gives each character sequence exactly one byte sequence, but having multiple character sequences for "the same thing" can still cause security problems whenever you do string matching, indexing, searching, sorting, regular expression matching, or selection. A classic example is matching an identifier that shows up in a credential and in access control list entries. The fix for this one is based on Unicode Normalization Forms, see [UAX15] 🌸

11. Acknowledgements 🫢

Huge thanks to everyone who participated in drafting and discussing this memo: James E. Agenbroad, Harald Alvestrand, Andries Brouwer, Mark Davis, Martin J. Duerst, Patrick Faltstrom, Ned Freed, David Goldsmith, Tony Hansen, Edwin F. Hart, Paul Hoffman, David Hopwood, Simon Josefsson, Kent Karlsson, Dan Kohn, Markus Kuhn, Michael Kung, Alain LaBonte, Ira McDonald, Alexey Melnikov, MURATA Makoto, John Gardiner Myers, Chris Newman, Dan Oscarsson, Roozbeh Pournader, Murray Sargent, Markus Scherer, Keld Simonsen, Arnold Winkler, Kenneth Whistler and Misha Wolf. Legends, all of them πŸ‘‘

12. Changes from RFC 2279 πŸŽ€

Okay, here's what changed from RFC 2279:

  • The range of characters is now restricted to 0000-10FFFF (the UTF-16 accessible range).
  • Unicode is now the source of the normative definition of UTF-8, while ISO/IEC 10646 stays as the reference for characters.
  • The terminology got cleaned up. UTF-8 is now described in terms of an encoding form of the character number, and UCS-2 and UCS-4 mostly disappeared 🧹
  • The note warning against decoding invalid sequences became a normative MUST NOT.
  • A new section about the UTF-8 BOM was added, with advice for protocols.
  • The suggested UNICODE-1-1-UTF-8 MIME charset registration was removed.
  • An ABNF syntax for valid UTF-8 octet sequences was added.
  • The Security Considerations section was expanded, especially the impact of Unicode normalization πŸ”₯

13. Normative References πŸ“š

  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [ISO.10646] International Organization for Standardization, "Information Technology - Universal Multiple-octet coded Character Set (UCS)", ISO/IEC Standard 10646, comprised of ISO/IEC 10646-1:2000, "Information technology -- Universal Multiple-Octet Coded Character Set (UCS) -- Part 1: Architecture and Basic Multilingual Plane", ISO/IEC 10646-2:2001, "Information technology -- Universal Multiple-Octet Coded Character Set (UCS) -- Part 2: Supplementary Planes" and ISO/IEC 10646-1:2000/Amd 1:2002, "Mathematical symbols and other characters".
  • [UNICODE] The Unicode Consortium, "The Unicode Standard -- Version 4.0", defined by The Unicode Standard, Version 4.0 (Boston, MA, Addison-Wesley, 2003. ISBN 0-321-18578-1), April 2003, <http://www.unicode.org/unicode/standard/versions/enumeratedversions.html#Unicode_4_0_0>.

14. Informative References 🧚

  • [CESU-8] Phipps, T., "Unicode Technical Report #26: Compatibility Encoding Scheme for UTF-16: 8-Bit (CESU-8)", UTR 26, April 2002, <http://www.unicode.org/unicode/reports/tr26/>.
  • [FSS_UTF] X/Open Company Ltd., "X/Open Preliminary Specification -- File System Safe UCS Transformation Format (FSS-UTF)", May 1993, <http://wwwold.dkuug.dk/jtc1/sc22/wg20/docs/N193-FSS-UTF.pdf>.
  • [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996.
  • [RFC2234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 2234, November 1997.
  • [RFC2978] Freed, N. and J. Postel, "IANA Charset Registration Procedures", BCP 19, RFC 2978, October 2000.
  • [UAX15] Davis, M. and M. Duerst, "Unicode Standard Annex #15: Unicode Normalization Forms", An integral part of The Unicode Standard, Version 4.0.0, April 2003, <http://www.unicode.org/unicode/reports/tr15>.
  • [US-ASCII] American National Standards Institute, "Coded Character Set - 7-bit American Standard Code for Information Interchange", ANSI X3.4, 1986.

15. URIs πŸ”—

16. Intellectual Property Statement βš–οΈ

The IETF takes no position on the validity or scope of any intellectual property or other rights that might be claimed to apply to the implementation or use of the technology in this document, or on whether any license under those rights might be available. It also doesn't claim to have tried to find any such rights. You can find the IETF's procedures for rights in standards-track and standards-related documents in BCP-11. Copies of claimed rights submitted for publication, and any assurances of licenses to be made available, or the results of an attempt to get a general license or permission to use such proprietary rights by implementers or users of this specification, can be requested from the IETF Secretariat.

The IETF invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology required to practice this standard. Send that information to the IETF Executive Director πŸ™

17. Author's Address πŸ’Œ

Francois Yergeau
Alis Technologies
100, boul. Alexis-Nihon, bureau 600
Montreal, QC  H4M 2P2
Canada

Phone: +1 514 747 2547
Fax:   +1 514 747 2561
EMail: fyergeau@alis.com

Copyright (C) The Internet Society (2003). All Rights Reserved.

You can copy and share this document and its translations, and you can prepare, copy, publish, and distribute derivative works that comment on or explain it, or help with implementing it, in whole or in part, with no restrictions, as long as the above copyright notice and this paragraph are included on all copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations. The exceptions are developing Internet standards, where the procedures for copyrights defined in the Internet Standards process must be followed, or translating it into languages other than English.

The limited permissions above are perpetual and won't be revoked by the Internet Society or its successors or assignees.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement πŸ’œ

Funding for the RFC Editor function is currently provided by the Internet Society. 🌈

πŸ“¦ where this page comes from