La conception des codes dans les systèmes métier — Comment définir les codes produit et client, et la clé de contrôle
· Go Komura · Conception de codes, Clé de contrôle, Systèmes métier, Base de données, C#, .NET, Excel, Tableau de décision, Conception, Développement Windows
« Nous migrons vers un nouveau système, merci de définir le système de codes produit » — cette question revient systématiquement lors de la construction d’un système métier ou de la migration d’un registre Excel. Et un code décidé sur un coup de tête finit, en moyenne, par survivre plus longtemps que le système lui-même : même si le système est remplacé au bout de dix ans, les numéros de client distribués aux partenaires et les codes produit imprimés sur d’anciens documents continuent d’exister.
Cela dit, la conception de codes bénéficie d’un patrimoine de savoir remarquablement riche accumulé par nos prédécesseurs. Les « numéros exploités à grande échelle » comme le code JAN, les numéros de carte bancaire ou le numéro individuel japonais (Mynumber) sont documentés publiquement, jusqu’aux raisons de chaque choix de conception, de la méthode de détection des erreurs de saisie à l’allocation des chiffres. Cet article s’appuie sur ce socle pour clarifier les règles à suivre pour définir un code produit, un code client ou un numéro de document dans un système métier, ainsi que le mécanisme exploitable qu’est la clé de contrôle.
1. La conclusion, d’abord
- Le code doit se limiter à l’identification, et le sens doit être porté comme un attribut dans la base de données. Un « code significatif » qui intègre le département, la catégorie ou l’année dans ses chiffres finit toujours par se casser lors d’une réorganisation ou d’un changement de catégorie. Le numéro individuel japonais (Mynumber) est conçu comme un numéro dépourvu de signification.1
- Ajoutez une clé de contrôle aux codes qu’une personne saisit, retranscrit ou lit à voix haute. Il est établi, par des mesures réelles, que la majorité des erreurs de saisie consistent en « une erreur de frappe sur un seul caractère » et en « une permutation de deux caractères adjacents »2, et la clé de contrôle vise précisément à détecter ces deux types.
- Le jeu de caractères se décide selon l’usage. Uniquement des chiffres si le téléphone, le fax ou l’écriture manuscrite sont impliqués. Pour économiser des caractères, un alphanumérique excluant les caractères prêtant à confusion (I, L, O, etc.), comme le Crockford Base323.
- Prévoyez un nombre de chiffres égal à « 10 fois le volume futur attendu, plus un chiffre », et si vous utilisez des zéros initiaux, traitez le code comme une chaîne de caractères dans l’ensemble du système. Dès qu’Excel interprète une valeur comme un nombre, il supprime les zéros initiaux et arrondit à 0 tout ce qui dépasse le 15ᵉ chiffre.4
- Un code déjà utilisé ne doit jamais être réutilisé, même s’il devient un numéro manquant. Les numéros conservés dans d’anciens documents, des journaux ou les systèmes des partenaires finiraient par désigner un objet différent.
- Si vous apposez un code-barres sur un produit destiné à la distribution, utilisez le code JAN (norme GS1) plutôt qu’un code maison.5
2. Faut-il donner du sens au code — le premier choix, et le plus déterminant
La première chose à décider dans la conception d’un code n’est ni le nombre de chiffres ni le jeu de caractères, mais « faut-il donner du sens au code ».
Une conception courante ressemble à ceci : « le code produit fait 8 chiffres ; les 2 premiers indiquent le département, les 3 suivants la catégorie, et les 3 derniers forment un numéro de séquence. » Au moment où on la décide, elle paraît bien ordonnée, mais voici ce qui se produit au bout de quelques années.
- Une réorganisation fusionne des départements, laissant en suspens les produits portant l’ancien code de département. Renuméroter casse la correspondance avec les anciens documents ; ne rien faire fait proliférer, dans le référentiel, des exceptions où « le département indiqué par le code diffère du département réel ».
- Un produit à cheval sur plusieurs catégories apparaît (à la fois alimentaire et non-alimentaire, par exemple), ce qui impose une règle interne pour décider quel code lui attribuer.
- Les produits d’une catégorie donnée augmentent au point d’épuiser les 3 chiffres du numéro de séquence, et l’on se retrouve à « emprunter, exceptionnellement pour cette seule catégorie, un numéro libre d’un autre département ».
La cause est claire : l’organisation et la classification sont amenées à changer, mais le code a été figé en partant du principe qu’elles ne changeraient pas. Le principe est donc l’inverse : faire du code un simple symbole qui désigne l’objet de façon unique, et porter les attributs comme le département ou la catégorie dans une colonne de la base de données. En tant qu’attribut, un simple UPDATE suffit quel que soit le changement, et le code reste intact.
Les systèmes de numérotation nationaux sont eux aussi construits selon ce principe. Le numéro individuel japonais (Mynumber) est un numéro de 11 chiffres dépourvu de sens, généré en convertissant le code du registre de résidence « par une méthode sans intervention arbitraire », suivi d’un chiffre de vérification.1 L’absence de sens sert à la fois à empêcher que l’on déduise des attributs personnels à partir du numéro, et à ce que ce numéro ne change pas lors d’un changement d’attribut (déménagement ou changement de nom).
Cela dit, dans la pratique, la demande de pouvoir « au moins distinguer un client d’un fournisseur d’un seul coup d’œil au début du code » reste tenace. Voici donc un tableau de décision.
| Méthode | Exemple | Points forts | Point de rupture | Cas d’usage adapté |
|---|---|---|---|---|
| Code entièrement significatif | 02-104-317 (département-catégorie-séquence) |
On lit les attributs directement | Renumérotation nécessaire en cas de réorganisation, de changement de catégorie, ou d’épuisement partiel des chiffres | Uniquement si les objets ne varient pas en nombre et si la classification est fixée par une règle institutionnelle |
| Numéro de séquence neutre | 10000317 |
Ne se casse quoi qu’il arrive. Numérotation simple | On ne peut rien déduire du code | Système où les attributs peuvent toujours être affichés en parallèle à l’écran ou sur les documents |
| Hybride | C-0317-5 (1 caractère de type + séquence + chiffre de contrôle) |
Évite uniquement la confusion de type. Facteur de rupture minimal | Changement de la définition du type (rare) | Le choix par défaut en cas de doute. Limitez le type à une granularité grossière du type « client / fournisseur / produit » |
Nous recommandons les deux dernières lignes du tableau. Considérez que plus vous intégrez de sens dans le code, plus vous multipliez les germes de rupture.
3. Jeu de caractères et nombre de chiffres — un compromis entre efficacité informationnelle et lisibilité
Le choix suivant porte sur le jeu de caractères et le nombre de chiffres. C’est une pure question arithmétique : plus le nombre de caractères possibles par position est élevé, plus on peut représenter d’objets avec le même nombre de positions.
| Jeu de caractères | Nombre représentable sur 6 chiffres | Résistance à la lecture orale / à l’écriture manuscrite |
|---|---|---|
| Chiffres uniquement (10 symboles) | 1 million | ◎ Solide pour le téléphone, le fax et l’écriture manuscrite |
| 32 symboles : lettres majuscules + chiffres, moins les caractères prêtant à confusion (Crockford Base323) | Environ 1,07 milliard | ○ Protégé contre les erreurs de lecture, mais moins pratique à l’oral que les chiffres |
| Lettres majuscules + chiffres (36 symboles) | Environ 2,18 milliards | △ La confusion entre 0 et O, ou entre 1 et I, se produit inévitablement |
Les deux critères de décision sont les suivants.
- Ce code sera-t-il lu au téléphone, écrit à la main ou envoyé par fax ? Si l’un de ces cas s’applique, nous recommandons d’utiliser uniquement des chiffres. Dès qu’une lettre s’y mêle, un coût de vérification (« I comme Isidore, ou 1 ? ») et un risque d’erreur de lecture apparaissent.
- Le nombre de chiffres devient-il trop long avec des chiffres seuls ? Ce n’est que lorsqu’on souhaite compresser le nombre de caractères — par exemple parce que le nombre d’objets dépasse plusieurs dizaines de millions — qu’il faut envisager l’alphanumérique. Même dans ce cas, plutôt que les 36 symboles bruts, il faut utiliser un alphabet déjà conçu à cet effet, comme le Crockford Base32, qui exclut
I,L,O(etU, pour éviter les mots grossiers accidentels). Cette spécification pousse la protection contre les erreurs de lecture jusqu’au bout : lors du décodage, elle accepte aussi les minuscules, et interprèteioulcomme1, etocomme0.3
Le nombre de chiffres se détermine non pas à partir du « nombre actuel d’objets », mais à rebours du « nombre d’objets susceptible d’être atteint sur les 20 à 30 ans de vie du système et des documents », en y ajoutant une marge d’un chiffre. Cela revient à dire qu’il faut prévoir un nombre de chiffres capable de représenter 10 fois le nombre d’objets susceptible d’être atteint (6 chiffres pour 100 000 objets). Si vous ajoutez une clé de contrôle, ce chiffre supplémentaire se compte séparément de cette marge (chapitre 4). Quand les chapitres 1 et 9 mentionnent « 10 fois le volume futur, plus un chiffre », cela désigne la somme du « corps du code = la partie ×10 » et du « chiffre de vérification = 1 chiffre ». Pour un volume prévu de 100 000 objets, cela donne 6 chiffres pour le corps + 1 chiffre de vérification, soit 7 chiffres au total.
Le chapitre 8 traite de la dangerosité du débordement de capacité, mais le coût pour éviter de déclencher, dans votre propre entreprise, une refonte générale comparable au passage du code postal japonais de 5 à 7 chiffres (en 1998), se résume à un seul chiffre supplémentaire.
Un autre point discret mais efficace est la séparation visuelle. Tout comme un numéro de carte bancaire est imprimé par groupes de 4 chiffres, un être humain ne peut manipuler correctement une longue suite de chiffres que par blocs de 3 à 4 chiffres. Pour un code de 8 chiffres ou plus affiché sur un document ou à l’écran, affichez-le séparé, par exemple 1234-5678. Le principe reste toutefois de ne pas inclure le séparateur dans les données, et de l’ajouter uniquement à l’affichage (chapitre 6).
4. La clé de contrôle — faire détecter les erreurs de saisie par le code lui-même
4.1 Les erreurs de saisie se résument en réalité à deux types
La clé de contrôle (le chiffre de vérification) est un chiffre ajouté à la fin (ou au début) d’un code, calculable à partir des autres chiffres, ce qui permet de détecter sur-le-champ une erreur dans le code saisi. Le chiffre de vérification du numéro individuel japonais a lui aussi un objectif explicitement inscrit dans le décret d’application : « confirmer l’absence d’erreur lors de la saisie dans un ordinateur ».1
La formule de calcul idéale dépend du type d’erreurs que commettent les humains. Selon l’étude classique de Verhoeff, fondée sur l’analyse de données d’erreurs de systèmes néerlandais de virement postal notamment, 60 à 95 % des erreurs sont des fautes de frappe portant sur un seul chiffre (single error) — de loin la majorité. Viennent ensuite les erreurs sur deux chiffres, qui représentent 10 à 20 % des cas, dont la plupart concernent deux chiffres adjacents, en particulier une permutation de type ab→ba (transposition). Les autres types (comme aa→bb, ou une permutation avec un chiffre intercalé) ne représentent chacun que 0,5 à 1,5 % du total environ.2
Autrement dit, la performance d’une méthode de clé de contrôle peut, dans les faits, s’évaluer sur deux critères : « dans quelle mesure détecte-t-elle une erreur sur un seul chiffre » et « dans quelle mesure détecte-t-elle une transposition de chiffres adjacents ».
4.2 Les méthodes réellement utilisées et leur capacité de détection (tableau de décision)
Avant de lire le tableau, clarifions la façon de lire les noms des méthodes. « Modulo XX » signifie « une méthode qui utilise le reste de la division par XX » (le modulo 11 utilise le reste de la division par 11). Le « poids » est le facteur multiplicateur appliqué à chaque chiffre : pour un « poids 3-1 », on multiplie alternativement par 3, par 1, par 3, par 1… en partant de la droite. Quelle que soit la méthode, le principe reste le même : « multiplier chaque chiffre par un facteur défini, faire la somme, et construire le chiffre de vérification à partir du reste de la division par un nombre défini ».
| Méthode | Utilisée pour | Erreur sur 1 chiffre | Transposition adjacente | Caractéristiques |
|---|---|---|---|---|
| Modulo 10, poids 3-1 | Norme GS1 (code JAN, etc.), ISBN-136 | Toutes détectées | Manque les paires dont la différence vaut 5 (05↔50, 16↔61, etc.) |
Le choix quasi obligatoire pour un usage avec code-barres |
| Luhn (modulo 10) | Numéros de carte bancaire7 | Toutes détectées | Manque uniquement la paire 09↔90 |
L’implémentation la plus simple. Le candidat par défaut pour un code maison |
| Modulo 11 (pondéré) | Numéro individuel japonais8, ancien ISBN | Presque toutes détectées | Presque toutes détectées | Capacité de détection élevée, mais avec le problème du « bouclage du reste » (voir plus bas) |
| Modulo 9 (pondéré) | Numéro d’entreprise japonais9 | Manque 0↔9 |
Manque la paire 0↔9 |
La division par 9 empêche de distinguer 0 et 9 |
| Damm / Verhoeff | Méthodes académiques | Toutes détectées | Toutes détectées | Implémentées par une table de correspondance numérique (Damm10) ou une opération de groupe (Verhoeff2) |
Quelques précisions complémentaires.
- La méthode JAN (modulo 10, poids 3-1) multiplie alternativement par 3 puis par 1 en partant du chiffre le plus à droite, additionne le tout, puis prend le chiffre des unités de « 10 − (le reste de la somme divisée par 10) » comme clé de contrôle.6 La somme reste inchangée après une transposition lorsque la différence entre le facteur 3 et le facteur 1, multipliée par l’écart entre les deux chiffres, est un multiple de 10 — c’est-à-dire lorsque l’écart entre les deux chiffres vaut exactement 5. Seul ce cas précis échappe à la détection.
- Luhn est une méthode déposée en brevet en 1954 par H. P. Luhn d’IBM7, qui double un chiffre sur deux et retranche 9 si le résultat dépasse 9, avant d’additionner le tout. La seule transposition adjacente qu’elle laisse passer est la paire
09↔90. Elle offre un bon équilibre entre simplicité d’implémentation et capacité de détection : c’est le premier choix à envisager pour adopter une nouvelle clé de contrôle sur un code maison, sans que cela pose problème. - Le modulo 11 du numéro individuel japonais offre, grâce au fait que 11 est un nombre premier, une capacité de détection théoriquement élevée, mais il comporte un repliement qui fixe uniformément la clé de contrôle à 0 lorsque le reste vaut 0 ou 18, ce qui rend indétectable uniquement une erreur qui fait basculer entre ces deux classes. L’ancien ISBN (ISBN-10), avec le même modulo 11, a résolu ce problème en « notant
Xle reste 10 », mais s’est ainsi retrouvé avec un inconvénient pratique : « un X apparaît là où l’on attendait un chiffre ». Adopter une famille de méthodes en modulo 11 implique nécessairement ce problème de « comment faire tenir 11 restes possibles dans 10 chiffres », ce qu’il faut savoir à l’avance. - Le modulo 9 du numéro d’entreprise japonais a la particularité rare de placer la clé de contrôle en tête du numéro11, mais comme il utilise le reste de la division par 9,
0et9deviennent congrus : une faute de frappe ou une permutation entre ces deux chiffres passe sans être détectée. - Les méthodes de Damm et de Verhoeff détectent la totalité des erreurs sur un seul chiffre et des transpositions adjacentes. Verhoeff a été le premier à construire un code décimal détectant la totalité des erreurs sur un chiffre et la totalité des transpositions adjacentes2, tandis que Damm a fourni une construction plus simple, qui se limite à consulter une seule table d’opération d’un quasi-groupe.10 Si la capacité de détection est la priorité absolue, ce sont ces méthodes qu’il faut choisir ; mais pour contrer les erreurs de saisie d’un système métier, Luhn ou la méthode JAN suffisent amplement en pratique.
Si ce tableau compare les méthodes sur les deux colonnes « erreur sur 1 chiffre » et « transposition adjacente », c’est parce que l’étude de Verhoeff vue en 4.1 — qui a compilé par catégorie les enregistrements d’erreurs de numéros réellement retranscrits et saisis par des personnes, notamment dans des systèmes néerlandais de virement postal — a montré que ces deux types représentaient l’essentiel des erreurs.2 Inversement, si la tendance des erreurs observées sur vos propres codes est manifestement différente (par exemple, une confusion majoritaire entre 1 et 7 en écriture manuscrite), il est plus efficace de revoir le jeu de caractères ou le format des documents que de comparer les méthodes de clé de contrôle.
4.3 Les codes qui doivent porter une clé de contrôle, et ceux qui n’en ont pas besoin
Le critère de décision est « le code passe-t-il par la main et l’œil d’une personne ? ». Cela vaut la peine d’en ajouter une à un code produit saisi à partir d’un bon de commande papier, à un numéro d’adhérent communiqué au téléphone, ou à un numéro de bon manuscrit rempli sur le terrain. À l’inverse, un identifiant interne qui ne circule qu’entre systèmes, ou un code qui n’est jamais saisi autrement que par sélection à l’écran, n’en a pas besoin : sans source d’erreur humaine, la détection n’a pas d’utilité.
5. Exemples d’implémentation — C# et Excel/VBA
Les principales méthodes s’implémentent toutes en quelques lignes à une dizaine de lignes. Veillez uniquement à toujours récupérer le code sous forme de chaîne de caractères (les raisons sont expliquées au chapitre 6).
C#
D’abord la méthode JAN (GTIN-13). Elle calcule la clé de contrôle à partir d’un corps de 12 chiffres.6
public static int Gtin13CheckDigit(string body12)
{
if (body12.Length != 12 || !body12.All(char.IsAsciiDigit))
throw new ArgumentException("Veuillez fournir 12 chiffres", nameof(body12));
int sum = 0;
for (int i = 0; i < 12; i++)
{
int digit = body12[11 - i] - '0'; // compter à partir de la droite
sum += (i % 2 == 0) ? digit * 3 : digit; // ×3 à droite, puis en alternance
}
return (10 - sum % 10) % 10;
}
Ensuite, Luhn. Pour un code client ou un numéro d’adhérent maison, ces deux méthodes suffisent.
public static int LuhnCheckDigit(string body)
{
int sum = 0;
for (int i = 0; i < body.Length; i++)
{
int digit = body[body.Length - 1 - i] - '0';
if (i % 2 == 0) // doubler un chiffre sur deux à partir de celui adjacent à la clé de contrôle
{
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
}
return (10 - sum % 10) % 10;
}
public static bool IsValidLuhn(string code) =>
code.Length >= 2 && code.All(char.IsAsciiDigit) &&
LuhnCheckDigit(code[..^1]) == code[^1] - '0';
Pour bien comprendre ce que fait ce code, le suivre une fois à la main aide à le retenir. Prenons 1000317 comme corps d’un code client, et calculons sa clé de contrôle. On double le 1ᵉʳ, le 3ᵉ, le 5ᵉ chiffre… en comptant depuis la droite du corps, et si le résultat du doublement dépasse 9, on lui retranche 9 — c’est tout.
| Position dans le corps (depuis la droite) | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| Chiffre | 7 | 1 | 3 | 0 | 0 | 0 | 1 |
| Doublé | ○ | ○ | ○ | ○ | |||
| Après calcul | 14→5 | 1 | 6 | 0 | 0 | 0 | 2 |
La somme vaut 5+1+6+0+0+0+2 = 14. La clé de contrôle est le chiffre des unités de « 10 − (le reste de la somme divisée par 10) », soit 10 − 4 = 6. Le code complet est donc 10003176, ce qui correspond bien à la valeur renvoyée par LuhnCheckDigit("1000317") ci-dessus.
Pour vérifier le code une fois complet, on compte depuis la droite en incluant la clé de contrôle, et on double le 2ᵉ, le 4ᵉ chiffre… en partant de la droite, avant de faire la somme. 6+5+1+6+0+0+0+2 = 20, ce qui est divisible par 10 : le code est donc correct. Essayons, à titre d’exemple, quelques fautes de frappe courantes.
- En cas de permutation de deux chiffres adjacents, tapé
10003716: 6+2+7+6+0+0+0+2 = 23. Non divisible par 10, donc l’erreur est détectée. - En cas d’erreur sur un seul chiffre, tapé
10008176: 6+5+1+7+0+0+0+2 = 21. Ceci aussi est détecté.
Comme le seul critère est « la somme est-elle un multiple de 10 », on peut vérifier ce calcul même sur le terrain avec une simple calculatrice. Comme on l’a vu au chapitre 4, Luhn ne laisse passer que la permutation 09↔90.
Voici aussi la vérification du numéro d’entreprise, utilisable pour le contrôle de saisie du référentiel des partenaires. Il s’agit d’une transcription directe de la formule du règlement ministériel9 (le premier chiffre est le chiffre de vérification, suivi des 12 chiffres du numéro de base).
public static bool IsValidCorporateNumber(string code)
{
if (code.Length != 13 || !code.All(char.IsAsciiDigit)) return false;
int sum = 0;
for (int n = 1; n <= 12; n++)
{
int p = code[13 - n] - '0'; // le chiffre le moins significatif du numéro de base est n=1
sum += p * (n % 2 == 0 ? 2 : 1); // ×1 pour les positions impaires, ×2 pour les positions paires
}
return 9 - sum % 9 == code[0] - '0';
}
En vérifiant avec l’exemple fourni par l’Agence nationale des impôts (le numéro d’entreprise et autres personnes morales 700110005901 → le numéro d’entreprise 8700110005901), on obtient : somme des positions impaires 11 + somme des positions paires 13 × 2 = 37 ; le reste de 37 divisé par 9 est 1 ; 9 − 1 = 8, ce qui correspond bien.11
Formules Excel et VBA
Lors de l’inventaire d’un référentiel existant dans Excel avant une migration, ou lorsque le service informatique contrôle une liste distribuée par le métier, on souhaite parfois vérifier sur place sans sortir d’un environnement de développement. Pour vérifier Luhn, une seule formule suffit (en supposant que le code se trouve dans A2, avec LET et SEQUENCE de Microsoft 365 ou Excel 2021 et versions ultérieures).
=LET(s,A2&"", n,LEN(s), i,SEQUENCE(n),
d,MID(s,i,1)*1,
x,IF(MOD(n-i,2)=1, d*2, d),
y,IF(x>9, x-9, x),
MOD(SUM(y),10)=0)
On double les positions où n-i est impair, c’est-à-dire le 2ᵉ, le 4ᵉ chiffre… en partant de la droite ; on retranche 9 si le résultat dépasse 9 ; on fait la somme, et on vérifie si elle est divisible par 10. C’est exactement la même procédure que le calcul manuel présenté plus haut. Attention : dans une cellule où le code est saisi comme un nombre, les zéros initiaux sont déjà perdus (chapitre 6). Convertissez la colonne en texte avant de vérifier.
Si vous souhaitez le distribuer y compris pour d’anciennes versions d’Excel, ou utiliser plusieurs méthodes selon les cas, il est préférable d’en faire une fonction VBA, appelable depuis la feuille de calcul comme =IsValidLuhn(A2).
' Vérification de la méthode Luhn. Toujours passer une chaîne de caractères pour ne pas perdre les zéros initiaux.
Public Function IsValidLuhn(ByVal code As String) As Boolean
Dim i As Long, n As Long, d As Long, total As Long
Dim c As String
n = Len(code)
If n < 2 Then Exit Function ' renvoie la valeur par défaut False
For i = 1 To n
c = Mid$(code, n - i + 1, 1) ' compter à partir de la droite
If c < "0" Or c > "9" Then Exit Function
d = CLng(c)
If i Mod 2 = 0 Then ' doubler le 2e, le 4e chiffre... en partant de la droite
d = d * 2
If d > 9 Then d = d - 9
End If
total = total + d
Next i
IsValidLuhn = (total Mod 10 = 0)
End Function
On peut écrire de la même manière la méthode JAN (×3/×1 en partant de la droite) ou le numéro d’entreprise (×1 pour les positions impaires, ×2 pour les positions paires) : seuls le facteur et le diviseur changent.
L’utilisation sur un écran de saisie mérite aussi un petit effort supplémentaire. Plutôt que d’afficher simplement « Code invalide » en cas d’incohérence de la clé de contrôle, interroger le référentiel et afficher le nom en retour (« 10003176 : Société XYZ, c’est bien cela ? ») permet aussi de faire capter par l’œil humain une erreur de saisie qui aurait échappé à la clé de contrôle (le cas où l’on a tapé, par erreur, un autre code réellement existant).
6. Les pièges immanquables sur le terrain
Même avec un bon système de codes, il existe des schémas classiques qui gâchent tout au niveau de l’implémentation et de l’exploitation.
- La perte des zéros initiaux et l’arrondi à 15 chiffres dans Excel. Quand Excel interprète le contenu d’une cellule comme un nombre, il supprime les zéros initiaux, et comme la précision effective d’un nombre est limitée à 15 chiffres, tout ce qui dépasse le 16ᵉ chiffre est remplacé par des 0.4 Un code client
00123devient123, et un long numéro de la taille d’un numéro de carte bancaire voit sa fin se transformer en0. Pour un code utilisé dans un système avec des échanges CSV, intégrez dès le départ dans la procédure d’exploitation le fait de le traiter comme une chaîne de caractères sur tout le trajet (spécifier le type texte dans Power Query, spécifier le type de colonne côté import). - Le stocker sous un type numérique en base de données. La disparition des zéros initiaux se produit de la même manière que dans Excel, et un
BETWEENdestiné à « filtrer sur une plage de codes » finit par inclure des codes de longueur différente. Un code n’étant pas destiné au calcul, le principe est d’utiliser un type chaîne de caractères à longueur fixe. Concevez également l’ordre de tri comme un tri de chaînes (avec une longueur fixe, le tri de chaînes équivaut au tri numérique). - Inclure le trait d’union dans les données. C’est fini dès que
1234-5678et12345678commencent à coexister comme des enregistrements distincts. Stockez le code brut, et n’ajoutez le séparateur qu’à l’affichage. À la saisie, retirez les traits d’union et les espaces avant de valider. - Les variations de casse. Si vous utilisez des lettres, normalisez-les en majuscules avant l’enregistrement, et unifiez-les vous-même plutôt que de vous reposer sur l’ordre de collation (collation) de la base de données.
- La réutilisation d’un numéro manquant. « Le code client 1000317 a résilié, autant le réattribuer à un nouveau client » est à proscrire absolument. Les anciennes factures, les journaux et les systèmes des partenaires conservent l’ancienne correspondance, ce qui ferait désigner une personne différente lors d’un audit ou d’une investigation d’incident. Le principe est qu’un code, une fois utilisé, ne sera jamais réutilisé.
7. Les codes qu’il ne faut pas définir soi-même — quand s’appuyer sur une norme existante
Un code qui reste interne à l’entreprise peut être conçu librement, mais si vous imprimez un code-barres sur un produit destiné à circuler à l’extérieur (commerce de détail, e-commerce, logistique), utilisez le code JAN (GTIN) plutôt qu’un code maison. Le code JAN se définit à partir d’un code d’entreprise GS1 obtenu en licence : il ne peut pas être décidé arbitrairement par l’entreprise elle-même.5 La méthode de calcul de la clé de contrôle est elle aussi fixée par la norme.6
Le point clé de conception, ici, est de ne pas chercher à unifier de force le code interne et le code JAN. Comme un même produit peut avoir des codes JAN différents selon le conditionnement, ou changer de code JAN lors d’une modification de spécification, la pratique standard consiste à conserver dans le référentiel produit un « code produit interne (équivalent à la clé primaire, numéroté par l’entreprise elle-même) » et un « code JAN (un attribut, pouvant en compter plusieurs) » comme deux colonnes distinctes. Le principe « le code identifie, le sens (la correspondance avec une norme externe) est un attribut » s’applique ici aussi directement.
8. La durée de vie et la migration d’un système de codes
Aussi soigneusement conçu soit-il, un système de codes finit toujours par atteindre sa limite de vie. Le cas typique est le débordement de capacité. Lorsque la limite supérieure du numéro de séquence approche, la seule option est « d’ajouter des chiffres » — mais le nombre de chiffres est gravé non seulement dans la définition des colonnes du référentiel, mais aussi dans la mise en page des documents, la largeur d’impression du code-barres, les spécifications des fichiers d’échange avec les partenaires, et jusque dans les systèmes de ces partenaires eux-mêmes. Il s’agit donc de mener, dans sa propre entreprise et chez tous ses partenaires, une migration comparable au passage du code postal japonais à 7 chiffres (en 1998).
C’est précisément pour cela que la « marge d’un chiffre » du chapitre 3 est utile, mais si une migration s’avère malgré tout nécessaire, voici les trois principes à suivre.
- Créez un référentiel de correspondance ancien/nouveau, et permettez la recherche avec les deux codes pendant la période de migration. Les demandes des partenaires arriveront avec l’ancien code.
- Si la clé interne et le code ont été séparés dès le départ, la migration se limite à un problème de couche d’affichage et de référentiel. Utiliser directement le code métier comme clé primaire de base de données entraîne dans son sillage les clés étrangères de toutes les tables. Pour une nouvelle conception, nous recommandons de séparer la clé interne (numérotation automatique) du code d’affichage.
- Distribuez les changements de schéma via des migrations versionnées. La méthode pour propager de façon fiable, à tous les clients et tous les environnements, une modification du nombre de chiffres d’une colonne de code, est celle traitée dans « Versionner le schéma de base de données ».
9. Conclusion
- Le premier principe de la conception de codes est « le code identifie, le sens est un attribut ». Graver le département ou la catégorie dans le code transforme directement tout changement d’organisation ou de classification en rupture du code. Ce n’est pas un hasard si le numéro individuel japonais est un numéro dépourvu de sens.1
- Le jeu de caractères et le nombre de chiffres relèvent d’un compromis entre efficacité informationnelle et lisibilité. Uniquement des chiffres en cas de lecture orale ou d’écriture manuscrite ; un alphabet protégé contre les erreurs de lecture (Crockford Base323) pour compresser le nombre de caractères. Le nombre de chiffres correspond à 10 fois le volume futur, plus un chiffre.
- La réalité des erreurs de saisie est la suivante : « 60 à 90 % sont des erreurs sur un seul chiffre, et l’essentiel du reste des transpositions adjacentes ».2 Ajoutez une clé de contrôle aux codes qui passent par la main humaine ; en cas de doute, choisissez Luhn, ou la norme GS16 pour un code-barres. Le problème du « bouclage du reste » des méthodes en modulo 11, et le fait que le modulo 9 du numéro d’entreprise ne distingue pas 0 et 9, sont des propriétés à connaître lors du choix de la méthode.
- Le principe d’implémentation est la cohérence en chaîne de caractères. La perte des zéros initiaux et l’arrondi à 15 chiffres dans Excel4, le stockage en type numérique, l’infiltration de traits d’union et la réutilisation de numéros manquants sont les quatre grands accidents du terrain.
- Un code produit destiné à circuler à l’extérieur doit s’appuyer sur JAN (GS1), et être conservé dans une colonne distincte du code interne. Séparez la clé interne du code d’affichage en prévision d’une future migration liée à un débordement de capacité.
Un système de codes est, une fois distribué, une « spécification externe de fait » dont le coût de correction ultérieure est sans commune mesure. Si la question des codes se pose lors de la définition des exigences d’un nouveau système, parcourez la liste de contrôle de cet article avant même de vous pencher sur les écrans ou les fonctionnalités.
Articles connexes
- Versionner le schéma de base de données d’une application métier — la pratique des migrations pour éviter que « chaque client ait une base différente »
- Remplacer un registre Excel par une liste SharePoint — en finir avec le « registre qui casse » grâce au partage, à l’historique et aux flux
- Automatiser les traitements Excel et CSV avec PowerShell — recettes pratiques d’agrégation, de rapprochement et de génération de documents
- Comment choisir le stockage local des données d’une application Windows — tableau de décision SQLite / JSON / registre / Access
Domaines de conseil associés
合同会社小村ソフト (Komura Software LLC) prend en charge la conception du système de codes et du référentiel lors de la construction ou du remplacement d’un système métier, l’investigation des débordements de capacité et des doublons dans un système de codes existant ainsi que la planification de la migration, et l’implémentation des contrôles de saisie (clé de contrôle, vérification par référentiel). Comme la comparaison des méthodes de clé de contrôle présentée dans cet article, nous prenons également en charge, dans le cadre du conseil en mathématiques appliquées, les consultations visant à évaluer par le calcul « quelle méthode détecte quel type d’erreur, et dans quelle mesure », afin d’en tirer une décision de conception.
- Développement d’applications Windows
- Modernisation et maintenance de logiciels Windows existants
- Conseil technique et revue de conception
- Conseil en mathématiques appliquées et optimisation des opérations
- Contact
Références
-
行政手続における特定の個人を識別するための番号の利用等に関する法律施行令(平成26年政令第155号) 第六条. Sur le fait que le numéro devant servir de numéro individuel est composé d’un numéro de 11 chiffres généré par conversion du code du registre de résidence selon une méthode sans intervention arbitraire, suivi d’un chiffre de vérification (un entier de 0 à 9 calculé dans le but de confirmer l’absence d’erreur lors de la saisie du numéro individuel dans un ordinateur). ↩ ↩2 ↩3 ↩4
-
J. Verhoeff, Error Detecting Decimal Codes, Mathematical Centre Tracts 29, Mathematisch Centrum, Amsterdam. Sur la fréquence des types d’erreurs, fondée sur l’analyse d’échantillons d’erreurs de systèmes réels (les erreurs sur un seul chiffre représentant le type le plus fréquent avec 60 à 95 %, les erreurs sur deux chiffres 10 à 20 % dont la majorité sont des transpositions de chiffres adjacents, et des types minoritaires comme le « twin error » représentant chacun 0,5 à 1,5 %), et sur le fait que l’auteur a construit un code décimal détectant la totalité des erreurs sur un chiffre et la totalité des transpositions adjacentes (le terme « transposition » dans cet ouvrage désigne l’échange de deux chiffres adjacents). ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Douglas Crockford, Base 32. Sur le fait que l’alphabet à 32 caractères exclut I et L, prêtant à confusion avec 1, ainsi que O, prêtant à confusion avec 0 (et U, pour éviter les mots grossiers accidentels) ; sur le fait que le décodage accepte à la fois les majuscules et les minuscules, et traite i et l comme 1, et o comme 0 ; et sur le mécanisme du symbole de contrôle par modulo 37. ↩ ↩2 ↩3 ↩4
-
Microsoft サポート, 先頭のゼロと大きい数値を保持する. Sur le fait que la précision effective d’un nombre dans Excel est limitée à 15 chiffres au maximum, que pour un nombre de 16 chiffres ou plus comme un numéro de carte bancaire, la partie au-delà des 15 premiers chiffres est remplacée par des 0, que les zéros initiaux sont supprimés, et sur le contournement consistant à traiter la colonne comme du texte. ↩ ↩2 ↩3
-
GS1 Japan, GS1事業者コード・GTIN(JANコード). Sur le fait que l’utilisation du code JAN nécessite une procédure d’enregistrement pour obtenir en licence un code d’entreprise GS1. ↩ ↩2
-
GS1 Japan, チェックデジットの計算方法. Sur le fait que la clé de contrôle du GTIN-13 (le format standard du code JAN) se calcule en multipliant alternativement par 3 puis par 1 en partant du chiffre le plus à droite, puis en soustrayant de 10 le reste de cette somme divisée par 10. ↩ ↩2 ↩3 ↩4 ↩5
-
H. P. Luhn, US Patent 2,950,048 “Computer for Verifying Numbers” (déposé en 1954, délivré en 1960). Sur la méthode qui ajoute une clé de contrôle à l’extrémité droite du numéro d’origine, et vérifie le numéro par une addition croisée utilisant des nombres de substitution (la somme des chiffres du nombre doublé). ↩ ↩2
-
行政手続における特定の個人を識別するための番号の利用等に関する法律に規定する個人番号、個人番号カード、特定個人情報の提供等に関する命令(平成26年総務省令第85号) 第五条. Sur la formule du chiffre de vérification (on multiplie le chiffre Pn situé à la n-ième position en partant du chiffre le moins significatif des 11 chiffres autres que le chiffre de vérification, par un poids Qn valant n+1 si 1≦n≦6 et n−5 si 7≦n≦11, on divise la somme par 11, et on soustrait le reste de 11 ; si le reste est inférieur ou égal à 1, il est ramené à 0). ↩ ↩2
-
法人番号の指定等に関する省令(平成26年財務省令第70号) 第二条. Sur la formule du chiffre de vérification du numéro d’entreprise (on multiplie le chiffre Pn situé à la n-ième position en partant du chiffre le moins significatif du numéro de base, par un poids Qn valant 1 si n est impair et 2 si n est pair, on divise la somme par 9, et on soustrait le reste de 9). ↩ ↩2
-
H. M. Damm, Totally anti-symmetric quasigroups for all orders n≠2,6, Discrete Mathematics, Vol. 307, 2007. Sur le fait qu’un quasi-groupe totalement antisymétrique, à la base d’une méthode de clé de contrôle détectant la totalité des erreurs sur un chiffre et des transpositions adjacentes, existe pour tous les ordres à l’exception de 2 et 6. ↩ ↩2
-
国税庁, チェックデジットの計算. Sur le fait que le numéro d’entreprise est composé d’un numéro de base à 12 chiffres précédé d’un chiffre de vérification, et sur l’exemple de calcul de la clé de contrôle 8 à partir du numéro d’entreprise et autres personnes morales 700110005901. ↩ ↩2
Articles associés
Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.
Versionner le schéma de base de données d'une application métier — pratiques de migration pour éviter que « chaque client ait une base différente »
Guide pratique pour versionner le schéma de base de données d'applications métier dont les bases sont dispersées chez chaque client. Impl...
CI/CD pratique pour les applications WinForms / WPF — Automatiser du build à la signature et à la distribution avec GitHub Actions
Guide pratique pour mettre en place le CI/CD des applications WinForms / WPF avec GitHub Actions. Couvre un YAML minimal de build+tests s...
Jusqu'à quand les applications VB6 continueront-elles de fonctionner ? — état du support du runtime et démarche concrète vers une migration .NET
Jusqu'à quand les applications VB6 continueront-elles de fonctionner ? Cet article clarifie l'asymétrie entre la politique de support du ...
Comment choisir la communication inter-processus sous Windows ── Tableau de décision : tubes nommés / TCP / gRPC / mémoire partagée / COM
Comment choisir le moyen de faire communiquer des applications Windows entre elles ? Cet article organise les tubes nommés, le TCP local,...
Pourquoi utiliser le Generic Host .NET et BackgroundService dans une application de bureau
Comment utiliser le Generic Host et BackgroundService pour organiser le démarrage, le traitement périodique, l'arrêt, la journalisation, ...
Sujets associés
Ces pages replacent le sujet dans un contexte plus large de services et de décisions.
Thèmes techniques Windows
Portail des sujets sur le développement Windows, l'analyse des incidents et la valorisation des actifs existants.
Services liés à ce sujet
Cet article est directement lié aux services suivants.
Développement d'applications Windows
Applications métier, intégration d'équipements et outils de communication, des besoins au développement.
Conseil technique et revue de conception
Clarification de la stratégie de modification, de la conception et du traitement des actifs existants.
Questions fréquentes
Questions souvent posées lors d’une consultation sur le sujet de cet article.
- À quels types de codes faut-il ajouter une clé de contrôle ?
- Ajoutez-la aux codes qui passent par la saisie, la retranscription ou la lecture à voix haute par une personne. Les cas typiques sont un code produit saisi à partir d'un bon de commande papier, un numéro d'adhérent communiqué par téléphone, ou un numéro de bon manuscrit. À l'inverse, un identifiant interne qui ne circule qu'entre systèmes (comme une clé primaire de base de données) n'en a pas besoin : sans intervention humaine, il n'y a pas d'erreur de frappe possible, et le but de la clé de contrôle est justement de détecter les erreurs de saisie. Le chiffre de vérification du numéro individuel japonais (Mynumber) précise d'ailleurs explicitement, dans le texte réglementaire, que son objectif est de « confirmer l'absence d'erreur lors de la saisie dans un ordinateur ».
- Peut-on faire porter au code produit le sens du département ou de la catégorie ?
- Le principe est que « le code se limite à l'identification, et le sens est porté comme un attribut dans la base de données ». Intégrer le département, la catégorie ou l'année dans les chiffres du code oblige à renuméroter à chaque réorganisation ou changement de catégorie, ce qui casse la correspondance avec les anciens documents et les numéros déjà communiqués aux partenaires. Si l'on tient absolument à ce qu'une personne puisse distinguer visuellement, un compromis pratique consiste à limiter cela à un seul caractère de préfixe indiquant le type, et à utiliser un numéro de séquence pour le reste.
- Peut-on ajouter après coup une clé de contrôle à un système de codes existant ?
- C'est techniquement possible, mais comme cela ajoute un chiffre, cela affecte le référentiel, tous les documents, les échanges de données avec les partenaires et les documents imprimés. Dans les faits, cela devient un projet de migration du système de codes ; il est donc réaliste de faire coïncider ce changement avec le moment où le système est de toute façon refondu, par exemple pour traiter un débordement de capacité. En attendant, se contenter, sur l'écran de saisie, d'une vérification de l'existence dans le référentiel (confirmer que le code saisi existe réellement) et d'un affichage du nom en retour peut déjà réduire considérablement les dégâts réels causés par une erreur de saisie.
- Peut-on utiliser un UUID ou un ULID comme code métier ?
- Cela ne pose pas de problème comme clé interne de base de données, mais cela ne convient pas au « code d'affichage » qu'une personne doit lire à voix haute ou retranscrire : un UUID, avec ses 36 caractères, est bien trop long pour être communiqué par téléphone ou par fax. Une architecture à deux niveaux — une clé interne (UUID ou numéro de séquence automatique) séparée d'un code d'affichage destiné aux personnes (un numéro de séquence court + une clé de contrôle) — permet de satisfaire les deux exigences à la fois. Même si le système du code d'affichage doit changer à l'avenir, tant que la clé interne reste stable, l'impact reste confiné à la couche d'affichage.
Profil de l’auteur
Page de présentation de l’auteur de l’article.
Go Komura
Représentant de KomuraSoft LLC
Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.