Making IBANs more memorable
Tags: bitcoin, mnemonic, iban, banking
Published: 2023-07-23 11:01:29

Or: "How I fixed IBANs with Bitcoin". This article is supposed to walk you through the journey I had while exploring an idea I had in mind for making IBANs more memorable.

The IBAN (International Bank Account Number) is a standardized international numbering system for bank accounts. It's used across countries to send money securely from one bank account to another.

In Germany, an IBAN might look like this: \`DE67834783927384738238\`. Now if you lend someone money for lunch (because they didn't have cash on them) and want it back, you would send them your IBAN. Now you have three options:

* Log in (and authenticate) to your banking app and copy & paste the IBAN
    
* Copy it out from your notes app, where you wrote it down before
    
* Take out your banking card and copy the IBAN number that is printed on it
    
* You both have PayPal, and you just share your email
    
* You are a maniac and know your IBAN by heart
    

All those options are a bit annoying and dependent on how often you find yourself in such a scenario, you might get pissed off about how unmemorable IBANs are. I am pissed off about how unmemorable IBANs are (in case you wondered).

## Inspiration

You might have heard of BIP-0039. No, you probably didn't, but you might have seen something like this:

```plaintext
canyon situate farm wedding cluster budget truck bag goose
obtain surround soda cable galaxy spoil utility tip remember
scan danger cat lawsuit staff riot
```

This is a Bitcoin wallet seed encoded in the so-called *mnemonic code*, which was proposed in [BIP-0039](https://en.bitcoin.it/wiki/BIP_0039). It is easier to remember, verbally communicate and write down than binary or hexadecimal data. This would be really handy to have for IBANs as well!

> I want my IBAN to be a 'simple cluster truck wedding bag goose soda galaxy'

The Bitcoin implementation comes with a few Bitcoin-specific add-ons, which we don't need. So we could just follow the implementation by [Oren Tirosh](https://web.archive.org/web/20100105040244/http://tothink.com/mnemonic/index.html), which everybody seems to reference when talking about mnemonic code.

## The Theory

The Mnemonic encoding by Oren works by taking a segment of bytes and calculating an index that maps to a word of a wordlist. This is not just one random wordlist extracted from a dictionary. The words are carefully selected by adhering to a set of criteria (which is heavily discussed on the internet), as seen [here](https://gist.github.com/fogleman/c4a1f69f34c7e8a00da8). So we just have to import some library and convert an IBAN into a bunch of bytes?

Well, first, we have to discuss how we actually convert an IBAN to bytes. We want to use as few bytes as possible since each extra byte will result in additional words, which one must remember.

## How IBANs work

But in order to be able to properly encode IBANs into bytes, we first have to understand what they are and how they work.

IBANs are defined in the ISO 13616-1 standard, which is actually quite readable (which I am not used to when reading standards). It defines that an IBAN consists of the following elements:

1. Two-letter country code, aka "alpha-2 code", according to ISO 3166-1
    
2. Checksum consisting of two numbers
    
3. Up to 30 characters and numbers called the "BBAN"
    

The BBAN has to have a fixed size per country code and also encode a bank identifier whose position and length are also fixed per country code.

This means that each country has its own "sub-standard" for IBANs (or BBANs, to be specific).

![](https://media3.giphy.com/media/v1.Y2lkPTc5MGI3NjExbmY4ZmExbzFwbTczczVuNTRyMjk0bDJzcHAyZjc5bTd3endxNXEzZyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ToMjGpIYtgvMP38WTFC/giphy.gif align="center")

The country code is often indexed by a numeric code that is bigger than 255, meaning it would not fit in one byte. But if you look at [the actual country code list](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes#Current_ISO_3166_country_codes), there are just 249 entries. This means by simply numbering them from 0 to 248, we can store that index in just one byte.

In theory, we could remove the checksum from the mnemonic code and [recalculate it](https://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits) when parsing the code, which would remove one byte. Since mixing up a word is more unlikely than mixing up a number, this could be a valid consideration. However, I think mixing up the order of words is still pretty likely, so some kind of verification check is still necessary.

Encoding the BAN is the difficult part: Each country has its own BBAN standard, as seen on [Wikipedia](https://en.wikipedia.org/wiki/International_Bank_Account_Number#IBAN_formats_by_country). It would be nice to have a way to support arbitrary IBAN numbers and convert them to bytes in the most space-efficient way. For this, one probably has to incorporate the country-specific BBAN specification to parse characters and numbers in the correct places (numbers need way fewer bytes than characters).

For German IBANs, it's quite easy: After the checksum, there are 18 numeric characters left to parse. The first 8 are the bank identifier, and the following 10 are the account number. These 18 numbers characters can be interpreted as a 7-byte integer. No ASCII characters, which would increase the byte representation in size. Together with the country code, we arrive at 8 bytes in total.

For comparison, here are some other countries with their IBAN format and required bytes:

| Country | IBAN Length | Format (excluding country code and check digits) | Bytes |
| --- | --- | --- | --- |
| Germany | 22 | 8 numeric (BLZ), 10 numeric (Account No.) | 8 |
| France | 27 | 5 numeric, 5 numeric, 11 numeric, 2 numeric | 11 |
| United Kingdom | 22 | 4 alphanumeric (Sort Code), 6 numeric, 8 numeric | 11 |
| Spain | 24 | 4 numeric, 4 numeric, 10 numeric, 2 numeric | 10 |
| Italy | 27 | 1 alphanumeric, 5 numeric, 5 numeric, 12 numeric | 12 |
| Netherlands | 18 | 4 alphanumeric, 10 numeric | 8 |
| Belgium | 16 | 3 numeric, 7 numeric, 2 numeric | 6 |

## Implementation

Most programming languages have libraries that already implement Oren's mnemonic encoder/decoder (e.g., [Python](https://pypi.org/project/mnemonic/) or [Rust](https://pypi.org/project/mnemonic/)).

So to implement the conversion from some IBAN string to mnemonic code, we would follow these steps:

1. Split the country code of the IBAN, so that checksum and BBAN remains
    
2. Calculate the index of the country code and convert it to a byte
    
3. Parse the checksum and BBAN as some big integer and convert them into bytes
    
4. Put the country code byte and other bytes together and feed them into the mnemonic encoding library
    

To implement parsing the mnemonic code into an IBAN, we would just reverse the steps. If we discarded the checksum while encoding, we would have to [recalculate it](https://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits) again. I also recommend verifying the IBAN using [its built-in checksum mechanism](https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN).

I would love to provide the source code of my implementation, but I would have to clean it up first. If you did a proper implementation of this, let me know!

## Further Considerations

This is a list of "add-ons" to this idea, which I might extend in the future.

By discarding the IBAN checksum and implementing a custom [crc-based checksum](https://en.wikipedia.org/wiki/Cyclic_redundancy_check), one could reduce the storage footprint of the checksum.

It would also be possible to separately encode the checksum in an extra word which is appended to the end. Then the "checksum word" would be optional, and the user could decide whether he wants to remember this additional word.

## Conclusion

This was a fun experiment that allowed me to dive deeper into topics that always interested me but never had a use case for. Maybe this idea is actually helpful - if you think so, let me know. I might write a simple web service that allows for an easy conversion. The problem with these things is that they are useless until not everybody (or some big banks) is adapting this. It would be really awesome if in the future, I could just enter some words into my banking app to send my money to someone. However, there are probably also some security considerations I haven't thought of.