Metadata-Version: 2.5
Name: cemacrib
Version: 0.1.0
Summary: Compute and check the CEMAC RIB check key, with a built-in bank code registry for the six member states
Author: Ulrich Bryand Tamouffe Teyo
License: Apache-2.0
License-File: LICENSE
Keywords: africa,bank,beac,cameroun,cemac,congo,gabon,iban,payments,rib,tchad,validation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# cemacrib

Calcul et contrôle de la **clé RIB de la zone CEMAC**, avec le référentiel des codes banque
des six États membres. **Zéro dépendance.**

```python
>>> import cemacrib
>>> cemacrib.compute_key("10005", "00010", "12345678901")
'93'
>>> cemacrib.validate("10005000101234567890193")
True
>>> cemacrib.registry.par_code("10005").nom
'Afriland First Bank Cameroun'
>>> cemacrib.registry.pays_du_code("40001")
'GA'
```

En ligne de commande :

```console
$ cemacrib cle 10005 00010 12345678901
93

$ cemacrib valider 10005000101234567890193
valide   cle 93

$ cemacrib valider 10005000101234567890293
invalide cle 93, attendue 90

$ cemacrib pays 40003000101234567890193
GA  Gabon
banque : BGFIBank Gabon
```

---

## Pourquoi

Un RIB de la zone CEMAC est un nombre de **23 caractères** en quatre blocs :

```
code banque (5) | code guichet (5) | numéro de compte (11) | clé (2)
```

Un chiffre tapé de travers dans le numéro de compte passe inaperçu à la lecture, et le virement
est **rejeté par la banque** — souvent après plusieurs jours et sans que la cause soit claire.
La clé existe exactement pour ça : elle vaut deux chiffres, entre `01` et `97`, et elle détecte
toute erreur de recopie sur un seul chiffre.

`cemacrib` la recalcule et la compare, avant l'envoi.

## L'algorithme

Deux formulations circulent pour la même clé, et elles sont **équivalentes** :

```python
# 1. la forme historique, celle des implémentations C
K = 97 - ((89*B + 15*G + 3*C) % 97)

# 2. la forme globale, celle des validateurs en ligne
K = 97 - ((N * 100) % 97)        # où N = B||G||C
```

Les coefficients `89`, `15` et `3` ne sont pas arbitraires : ce sont exactement les restes de
`10^18`, `10^13` et `10^2` modulo 97. C'est ce qui rend les deux expressions congrues quel que
soit le RIB. Le test `test_les_deux_formules_sont_equivalentes` vérifie d'abord cette
congruence, puis la contrôle sur 2 000 RIB tirés au hasard — c'est ce qui autorise à faire
confiance à la formule courte.

### Le piège des lettres

Un numéro de compte peut contenir des lettres. La table de conversion procède par groupes de
neuf, **et le troisième groupe démarre à 2** :

| | | | | | | | | |
|---|---|---|---|---|---|---|---|---|
| A | B | C | D | E | F | G | H | I |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| J | K | L | M | N | O | P | Q | R |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| S | T | U | V | W | X | Y | Z | |
| **2** | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |

Un simple modulo 9 donnerait `S = 1` et fausserait la clé d'un cran. C'est l'erreur la plus
courante des implémentations recopiées de mémoire, et `test_le_piege_du_troisieme_groupe` la
verrouille.

## Le référentiel

**63 établissements** dans les six pays, avec le pays déduit du premier chiffre du code banque :

| Premier chiffre | Pays | Plage |
|---|---|---|
| `1` | Cameroun | 10001 – 12003 |
| `2` | République Centrafricaine | 20001 – 20005 |
| `3` | Congo | 30005 – 32002 |
| `4` | Gabon | 40001 – 42001 |
| `5` | Guinée Équatoriale | 50001 – 52001 |
| `6` | Tchad | 60001 – 62001 |

Les plages `12001`, `32001`, `42001`, `52001` et `62001` sont les trésors publics et les
services postaux : ce ne sont pas des banques commerciales, mais ils émettent bien des RIB.

```python
>>> cemacrib.registry.par_pays("CM")[0]
Banque(code='10001', pays='CM', nom="Banque Internationale du Cameroun pour l'Epargne et le Credit")
```

## Ce qu'il ne fait pas

- **Il ne dit pas si un compte existe.** Il dit si le RIB est *bien formé* et si sa clé est
  juste. Un RIB parfaitement valide peut désigner un compte fermé.
- **Il ne fait pas d'IBAN.** La CEMAC n'utilise pas l'IBAN : le format est le RIB à 23
  caractères, hérité de l'espace OHADA.
- **Le référentiel n'a pas été recoupé avec une source officielle.** Voir ci-dessous.

## Provenance du référentiel — à lire

Le référentiel a été relevé sur `rib.finohada.com` le **12 octobre 2026**. Les codes bancaires
sont des faits, non protégeables, mais **cette liste n'a pas été recoupée avec une source
officielle de la BEAC** : `beac.int` était injoignable au moment du relevé.

**Un doute connu et laissé visible** : l'entrée `30011` porte le nom « Banque Centrale du
Congo ». C'est le nom de la banque centrale de la République *démocratique* du Congo, qui
n'appartient pas à la CEMAC. Erreur du référentiel d'origine, ou homonyme — à trancher. Le nom
porte la mention `DOUTE` et le test `test_le_doute_sur_30011_est_documente` empêche qu'on le
corrige en silence.

**Vérifiez chaque entrée avant un usage en production.**

## Tests

```console
$ python -m unittest discover -s tests -t . -v
...
Ran 27 tests in 0.202s

OK
```

## Licence

Apache-2.0.
