Obsidian Note Codes

🦔 🦔 🦔

Obsidian with the Note Code plugin on the bottom right showing the code for a note about hedgehogs.
Obsidian with the Note Code plugin on the bottom right showing the code for a note about hedgehogs.

I made a little plugin for Obsidian: Note Codes.

It will assign a 4-character code to every note in your Obsidian vault. Those codes let you quickly reference notes in your vault from other places such as hand-written notes.

Click here to try it out.

To make things nicer, there's also a protocol handler, so something like obsidian://note-codes/open?code=XX-XX will open the note with the code XX-XX.

I tried to make these codes look nice even if they are handwritten. They're just four characters and some of the similar-looking ones are removed (though the plugin is smart enough to know that AA-0A is the same as AA-OA.

As usual, it's all open source: https://github.com/SilverEzhik/obsidian-note-codes

What's in a note code?

Note codes are generated based on a note's name and path, meaning that the note code will change if you rename your note.

Each note code consists of 4 alphanumeric characters. For clarity, O, I, L, and U are excluded from the codes, but this plugin will automatically handle these correctly - so OI-LU will automatically be treated as 01-1V when searching. Same with the missing dash or lowercase letters.

Note codes are generated by SHA-256-hashing the note's path in the vault, then taking the first 20 bits of the hash and encoding them using Douglas Crockford's Base32 encoding scheme.

32^4 = 1,048,576, which is hopefully enough.


Hi Hacker News

Looks like this extension made it on the orange website: https://news.ycombinator.com/item?id=45288739

I got some interesting feedback—the first is that probability of note code collisions can be a pretty high due to the birthday paradox and the second is that if you rename a note, its code will change.

Both of these are consequences of how I chose to generate note codes. As said above, note codes are generated based off the note's path relative to the vault root. This means that note codes will be as stable as the note's name and path and won't be tied to Obsidian in any way—generating the note code is as simple as:

import hashlib

def hash_string(s):
    h = hashlib.sha256(s.encode()).digest()
    n = ((h[0] << 16) | (h[1] << 8) | h[2]) % (32**4)
    a = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
    r = ''.join(a[n // 32**(3-i) % 32] for i in range(4))
    return f"{r[:2]}-{r[2:]}"

But it does come at the cost of the note code changing if the note is renamed.

I don't have a good answer to this. I don't think it's a good idea to tie note codes to Obsidian like that, but at the same time, the renaming problem is quite annoying—after all, Obsidian doesn't (as of me writing this) provide an API to go into the real world and rename every instance of a note name the way it can in the vault. So these note codes are only as stable as a deep link into Obsidian.

So far, I'm contemplating a small improvement on this. I still want to keep note codes as they are, however, I'd like to keep some sort of a vault-specific cache of note codes previously assigned to a note. This way, even if you rename a note, at least within the same vault, you'd still be able to access it via its previous note codes.

As for the birthday paradox, oops. I think ultimately it's not a critical issue. The worst case scenario here is that you'll look up a note code and then see multiple matches in the search panel. I honestly don't think this one can be solved any other way besides tying note codes to the Obsidian vault. Is it worth it? You tell me.

🦔 🦔 🦔

Discuss on MastodonDiscuss on Bluesky