Le BOCU-1 est un schéma de transformation du texte, compatible avec le répertoire universel d’Unicode et ISO/CEI 10646, en séquences d’octets. Il tire son nom de l’acronyme anglais de Binary Ordered Compression for Unicode (« compression ordonnée binairement pour Unicode »), qui décrit une méthode brevetée de codage plus générale, et dont BOCU-1 est une des variantes possibles ; cette variante est standardisée de façon très stricte (de façon bien plus limitative que la méthode de codage BOCU qui a d’autres applications que le seul codage du texte) et réutilisable sous cette forme dans des applications libres (sous certaines réserves concernant certaines modifications qui restent interdites sans l’obtention préalable d’une autorisation et d’une licence spécifiques si ces modifications ne sont pas strictement conformes à la spécification de cette seule variante).

Comme UTF-8, BOCU-1 est compatible avec MIME et les formats de fichiers texte usuels, car il laisse les codes de contrôle C0 essentiels (utilisés comme séparateurs de ligne ou de page) ainsi que les blancs (espaces normales et tabulations) codés sous forme d’octets simples qui ne servent pas non plus à représenter d’autres caractères multi-octets. Et comme UTF-8 (mais pas UTF-16 ou SCSU), il conserve au niveau binaire l’ordre de tri des valeurs scalaires des points de code. Cependant BOCU-1 n’est pas utilisable tel quel pour coder les noms de documents et dossiers (dans les systèmes de fichiers), ni dans les URL.

Intérêts Son intérêt par rapport à UTF-8 (dans son utilisation pour MIME) réside dans la meilleure compression de données qu’il permet sans nécessiter d’algorithme compliqué de traitement : il offre un taux de compression comparable à UTF-8 pour les langues latines (anglais, français, allemand, roumain, suédois, tchèque, etc.). Il offre des taux de compression comparables à UTF-16 (et bien meilleur qu’UTF-8) pour les langues à écriture idéographique (notamment le chinois, le japonais) ainsi que pour le coréen (dans l‘écriture alphasyllabure hangul).

Comme UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE (mais à l’inverse de SCSU, ou même UTF-16 et UTF-32 qui sont dépendants de l’ordonnancement des octets dans les unités de codage sur 16 ou 32 bits et de la présence ou non d’un code « BOM », de l‘anglais Byte Order Mark, en tête de texte), il est totalement prédictif (il n’existe qu’une seule façon de coder en séquences d’octets une même séquence de points de code composant un texte).

Mais par rapport à UTF-8 et UTF-16, il améliore la compression du coréen transcrit seulement dans l’alphabet jamo de base.

Il offre un meilleur taux de compression (comparable à celui offert par SCSU) qu’UTF-8 et bien meilleur qu’UTF-16 pour les langues utilisant d’autres écritures qui utilisent la plupart du temps un nombre réduit de caractères, pris soit dans un même bloc de 128 points de code, soit parmi les codes de contrôles C0 et l’espace standard, en obtenant des taux également comparables aux codes des pages de codes et jeux de caractères 8 bits ou multioctets qui ont été développés dans le passé pour certaines langues ou familles de langues, tout en permettant d’être compatible avec la totalité du répertoire universel de l’UCS. C’est le cas de toutes les écritures alphabétiques simples, notamment l’écriture grecque (pour la transcription du grec moderne monotonique ou l’ancien grec classique, mais aussi pour le grec polytonique), cyrillique (pour la transcription du russe, bulgare, ukrainien, etc.), ou les abjads sémitiques (arabe, hébreu), et la plupart des abugidas brahmiques (comme la dévanagari pour la transcription de l’hindi ou du sanscrit, l’écriture tamoule, les écritures thaïe, khmère, lao, les écritures philippines, etc.)

Principes de codage Le codage BOCU-1 est contextuel et orienté vers le codage en suite d’octets indivisible. Il n’utilise qu’une seule variable d’état entière (contenant la valeur scalaire d’un point de code unique dépendant seulement d’un seul point de code précédemment encodé, donc limité à 21 bits).

Il ne doit être utilisé que pour coder sous la forme de séquences d’octets des suites de points de code standards dotés d’une valeur scalaire dans les normes ISO/CEI 10646 et Unicode (donc uniquement dans U+0000 à U+D7FF, ou U+E000 à U+10FFFF). Comme les autres schémas de transformations conformes à Unicode (tels que UTF-8), il autorise le codage des non-caractères (tels que U+FFFE..U+FFFF) et uniquement ceux-ci (contrairement au codage GB-18030 utilisé en République populaire de Chine, et qui permet de coder aussi la totalité des points de code standards de l‘UCS, mais qui contient aussi des extensions permettant, temporairement, de représenter des caractères non encore normalisés dans l’UCS au niveau international au moyen d’un nombre plus important de positions d’usage privé dans leur mappage possible vers l’UCS, mais réservées dans un registre permanent au sein de cette norme nationale).

La variable d’état La variable d’état prend une valeur initiale fixe, qui est restaurée après chaque occurrence d’un caractère de contrôle C0 dans le texte (U+0000 à U+001F) et qui correspond au milieu de la colonne des 128 caractères de l’US-ASCII : U+0040.

L’encodage BOCU d’un nouveau point de code dépend de celui-ci : Si ce nouveau point de code est le caractère d’une espace normale, U+0020, l’octet 0x20 est émis, mais la variable d’état n’est pas modifiée. Si ce nouveau point de code est celui d’un des trente-deux caractères de contrôle C0 (U+0000 à U+001F), l’octet de même valeur scalaire est émis, et la variable d’état prend la valeur U+0040 (au milieu du bloc latin de base) : cela permet une resynchronisation du flux sur les sauts de lignes. Sinon, ce nouveau point de code est codé avec une longueur variable sur un à quatre octets (mais sans utiliser aucun des douze octets invariants réservés pour MIME, ni l’octet 0x20 représentant l’espace U+0020), calculés selon la différence delta entre les valeurs scalaires de ce nouveau point de code et de celui stocké dans la variable d’état.

La variable d’état n’est pas modifiée après le codage d’une espace (U+0020), afin de ne pas briser le taux de compression dans les textes non latins les plus courants (ce n’était pas le cas dans la version initiale appelée simplement « BOCU » par ses concepteurs, et que la version BOCU-1 référencée par la note technique UTN#6 d’Unicode a améliorée sur ce point).

Dans tous les autres cas, la variable d’état prend la valeur d’un point de code au milieu du bloc dans lequel se situe le dernier caractère qui a été encodé. Des exceptions sont faites pour les écritures nécessitant des blocs plus larges ou non alignés sur des multiples de 128 points de code : après le codage d'un caractère du bloc hiragana (U+3040 à U+309F), la variable d’état prend la valeur du point de code au milieu de ce bloc (U+3070). après le codage d’un caractère sinographique du bloc CJK Unihan (U+4E00 à U+9FA5), la variable d’état prend la valeur du point de code au milieu de ce bloc (U+76D2). après le codage d’un caractère du bloc des syllabes hangul précomposées (U+AC00 à U+D7A3), la variable d’état prend la valeur du point de code au milieu de ce bloc (U+C1D1). dans les autres cas, la variable d’état prend la valeur du dernier point de code, arrondie au multiple de 128 inférieur puis auquel on ajoute 64.

Points de codes codés de façon invariante et synchronisation Les douze caractères de contrôle invariants pour MIME, et qui sont toujours codés avec le même octet quelle que soit leur position dans le texte sont : U+0000, codé 0x00 dans BOCU-1 : le caractère de bourrage (null, abrégé NUL) ; U+0007, codé 0x07 dans BOCU-1 : le caractère d’alarme (bell, abrégé BEL) ; U+0008, codé 0x08 dans BOCU-1 : l’espace de correction arrière (backspace, abrégé BS) ; U+0009, codé 0x09 dans BOCU-1 : la tabulation horizontale (tabulation, abrégé TAB) ; U+000A, codé 0x0A dans BOCU-1 : le saut de ligne (line feed, abrégé LF) ; U+000B, codé 0x0B dans BOCU-1 : la tabulation verticale (vertical tabulation, abrégé VT) ; U+000C, codé 0x0C dans BOCU-1 : le saut de page (form feed, abrégé FF) ; U+000D, codé 0x0D dans BOCU-1 : le retour chariot (carriage return, abrégé CR) ; U+000E, codé 0x0E dans BOCU-1 : le contrôle de sortie hors-code (shift out, abrégé SO) ; U+000F, codé 0x0F dans BOCU-1 : le contrôle de retour en-code (shift in, abrégé SI) ; U+001A, codé 0x1A dans BOCU-1 : le contrôle de substitution (substitute, abrégé SUB), également utilisé dans les fichiers textes compatibles DOS et CPM comme marqueur de fin de fichier ; U+001B, codé 0x1B dans BOCU-1 : le contrôle d’échappement (escape, abrégé ESC) ; (Ces douze caractères de contrôle s’ajoutent à l’espace normale U+0020 codée 0x20 et décrite ci-dessus, qui est aussi invariante mais ne déclenche pas de réinitialisation de la variable d’état et ne peut donc pas servir à la resynchronisation du flux).

Les 20 autres caractères de contrôle C0, bien que codés aussi eux-mêmes en utilisant un seul octet de valeur scalaire identique (afin de préserver l’ordre de tri binaire), sont aussi utilisés comme octets suffixe dans la représentation différentielle des autres caractères.

On peut noter que certains protocoles de transport ou protocoles de liaison pour le transport de données (y compris le texte) utilisent d’autres caractères de contrôle pour l’encapsulation de données dans des trames (notamment U+0002 [STX] et U+0003 [ETX] et U+0016 [SYN]), le contrôle de flux (notamment U+0011 [DC1/XON] et U+0014 [DC4/XOFF]), l’acquittement (hors-bande) de commandes (notamment U+0006 [ACK] et U+0015 [NAK]), le bourrage (notamment U+007F [DEL]), l’annulation anticipée d’une séquence ou commande en cours non acquittée (U+0018 [CAN]), et la transparence des données encapsulées (notamment avec U+0010 [DLE]). Ces contrôles ne sont pas préservés (mais réencodés différemment à l’aide des valeurs deltas décrites ci-dessous) dans BOCU-1 qui sera incompatible avec ces protocoles (qui disposent parfois de dispositifs d’échappement permettant de transporter ces caractères de façon transparente, mais nécessitant l’emploi d’un des contrôles susmentionnés). La plupart de ces protocoles sont aujourd’hui désuets et remplacés par des protocoles assurant une totale transparence des données encapsulées à l’aide de codages binaires plus efficaces (par exemple les protocoles de transport TCP/IP de l’Internet ou les trames compatibles Ethernet des normes IEEE 802).

À ces valeurs d’octets fixes s’ajoute une valeur réservée qui ne représente elle-même aucun point de code et ne peut figurer non plus comme premier octet du séquence multi-octet représentant un point de code : la valeur d’octet 0xFF est réservée comme code reset spécial pour la resynchronisation (il ne sera codé que pour forcer la variable d’état à sa valeur initiale U+0040 : cela brise effectivement l’ordonnancement binaire des points de code (cet octet ne représentera donc pas un caractère) ; il peut être utilisé comme terminateur de texte ou comme séparateur de clés de tri textuelles puisqu’il est supérieur à tous les autres octets utilisés pour le codage des points de code, mais il ne pourra pas être utilisé comme octet préfixe au milieu d’un texte codé BOCU sans briser le tri binaire) ; mais cette valeur pourra être utilisée aussi pour les octets suffixes servant à coder les grandes valeurs de deltas sur plusieurs octets (voir ci-dessous).

Codage différentiel des autres points de code Le codage différentiel des autres points de code dotés d’une valeur scalaire (caractères ou non-caractères) doit permettre de coder distinctement des différences positives ou négatives entre tout point de code possible et celui contenu dans la variable d’état : les petites différences (valeurs de delta positives ou négatives) nécessitent moins d’octets que les grandes différences.