Remix.run Logo
Obsidian Note Codes(ezhik.jp)
114 points by surprisetalk 6 days ago | 56 comments
sethaurus 2 days ago | parent | next [-]

(From the article, talking about the number of available codes)

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

Unfortunately, it really isn't enough. Since these 4-character codes are based only on a hash of the note's filename, and there's no other collision-resistance built in, the likelihood of two notes getting the same code rises very quickly. With 500 notes in the vault, the chance of two notes having the same code is about 1-in-10. At 900 notes, the odds are 1-in-3, and at 1200 notes, the chances of a collision rise above 50%: it's more likely that there will be a collision than not. These are realistic numbers of notes for an Obsidian vault.

This is all solvable by having something allocating IDs (and attaching them to the notes), but when using a hash, 32 bits just isn't enough to give uniqueness at even small scales.

Ezhik 2 days ago | parent | next [-]

(developer here)

Thanks for raising the birthday paradox problem.

The search panel should show all the notes with the same code, so hopefully even with collisions you'd still be able to tell from context which note you're looking for.

I did consider allocating IDs, but I'm a bit worried about this tying notes to a specific Obsidian vault - with the way note codes work now, there is no dependence on the vault itself, only on the note's name. Something to think about...

spott a day ago | parent | next [-]

I like the idea of throwing the note code in the frontmatter of the note.

Then it is stable, not tied to the vault, not tied to the name, can be customized on a per note basis if a user wants (00-00 is a specific note for example), and can be deduplicated within a vault.

jlaternman a day ago | parent [-]

Agreed, this would be a nice setting to "burn in" the codes to frontmatter on e.g first save. And with this enabled the plugin could also check for and avoid duplicates by modifying the code until its unique).

One other possibility is use git log --follow to grab the original filepath + commit hash, to base the code on. Imperfect but should reduce code changes vs. on rename.

I really like the simple 4 letter code for shorthand!

Ezhik 20 hours ago | parent [-]

It's an interesting idea - sadly the problem with it is that there's no way to add these tags to other kinds of files that don't have frontmatter. Not sure how to best to deal with it. Right now I'm leaning towards having some vault-specific storage for it.

jlaternman 29 minutes ago | parent [-]

Ah yep, I hadn't considered these codes appear for all files, not just frontmatter-friendly formats, which my vaults mostly are… Watermarks for media files? EXIF? — I joke.

It's an interesting problem to think on and also reminds me of resource fork advantages. My two cents is it's worth having a setting for "more permanent" codes at whatever compromise it forces. The idea of very short note codes is really nice, especially if it's "that's the code, it won't change" (I constantly rename and move notes to improve organisation and I expect others do) — I'll be trying out your plugin soon!

The Git idea was to track the original commit of note, assuming the vault is in a repo, and use that original path + git hash as the thing that doesn't change. Log tracking is imperfect, but I'd expect it to work in a vast majority of cases in Obsidian context.

medstrom 2 days ago | parent | prev | next [-]

You're lucky to regard note names as stable enough that they work as unchanging IDs for you!

But is it not then the same thing, because you already "allocated an ID" by naming it? Did you, before coming up with the 4-char hash, often label things outside the vault with the same names as those found in your vault?

Ezhik 2 days ago | parent [-]

I keep a paper journal and refer to my Obsidian notes once in a while.

inhumantsar a day ago | parent | prev [-]

maybe pick an ID at random, record it in a "used" list, and store the code in the note as a property? an event handlers(1) could manage removing used codes from the list when a note is deleted. likewise, another handler could check if new notes (ie those imported from another vault) already have an ID and register it as used or ask the user if they want to generate a fresh ID.

[1] https://docs.obsidian.md/Plugins/Events

xnorswap 2 days ago | parent | prev [-]

> 32 bits just isn't enough to give uniqueness at even small scales

You're right, but it's actually just 20 bits here, not even 32 bits.

1dom 2 days ago | parent | prev | next [-]

I feel this needs more explanation as to why and what problem is being solved.

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

I get the idea of assigning a short identifier to things, but then why would I ever want that ID to change when I change random properties about the note?!

It was interesting to read about the idea of 4 characters with minimal similar looking characters, but the application of that here seems like a solution looking for a problem.

wiether 2 days ago | parent [-]

Same reaction here.

I could see it being useful... until it said that changing the note name will change its code.

It's the exact opposite of how it should work. It's also the exact opposite of how Obsidian works, automatically updating references to a note when you rename it.

Ezhik 2 days ago | parent [-]

(developer here)

Interesting to hear that you think this is the opposite of how Obsidian works. I specifically opted for this approach so that these note codes are entirely independent of Obsidian itself and can be ported over to other solutions.

The other way to do it would be to store note codes in some vault-specific storage, but then those codes would be tied to Obsidian, which worries me a bit.

That said, I do want to figure out a nice way to improve it. One idea I've had was to introduce a cache of sorts, so that the plugin will remember all the older codes a note previously had. Do you think this would help your use case?

wiether 2 days ago | parent | next [-]

I'm starting to think that I completely misunderstood the goal of your plugin.

I understood that it provided a unique identifier for a note, that could be referenced elsewhere. Meaning that I expect it to last the lifetime of the note. Like a SSN for instance.

But when you talk about being tied to Obsidian, I'm not sure I follow. If it's an identifier to an Obsidian note, sure, the ID should be tied to Obsidian. But if it's an identifier to a .md file, then the ID should not be tied to Obsidian.

For the second case, it's not an issue: think about Obsidian as an IDE, and your vault as a GIT repository. You can create your own ID logic, idependant of Obsidian itself, but stored in the vault. Your pluging will implement this logic, and add the necessary requirements to make it work in Obsidian. And you could make a plugin for VSC that would implement the same logic, and adding the requirements to make it work in VSC.

In this case, I would expect the note ID to be the same, weither I access the vault (GIT repo) through Obsidian or VSC.

Ezhik 2 days ago | parent [-]

That's a good point. I'll consider it for the next version.

unfamiliar 2 days ago | parent | prev [-]

What problem is it aiming to solve (that the file name doesn't already solve)?

Ezhik 2 days ago | parent [-]

Being too lazy to write out the whole file name :)

sfkgtbor 2 days ago | parent | prev | next [-]

Very interesting to see another person also landing on using 4 base32 characters for labeling things - it really is enough for a human.

Personally I use it for labeling physical things - mainly boxes. With a corresponding note in my Obsidian vault it really helps with getting content, context, and history about random stuff in my basement.

Python oneliner for generating them I've aliased in my Bash config: python3 -c "import base64; import secrets; print(''.join(secrets.choice(base64._b32alphabet.decode()) for _ in range(4)))"

fastball 2 days ago | parent | next [-]

The space has 1M IDs available, which sounds like enough until you take into account how the probability of collision works (birthday problem). With only 1200 notes (not many in my experience running a notes platform), your probability of collision is already about 50%.

medstrom 2 days ago | parent [-]

Aye, so this is fine as long as there's just one entity generating IDs, so it can automatically check for collision and re-generate.

In a distributed system it's another matter.

I'm currently using 6 base-40 chars (upcase and lowcase letters, so e.g. "SXJwzQY") that represent an integer Unix time.

The base-40 alphabet is enough that all IDs up until year ~2099 will fit in 6 chars, and it's nicer to type on the phone when you only have to switch between two keyboard modes, the upcase and lowcase but not also the numbers and symbols mode.

mungoman2 2 days ago | parent | prev [-]

Interested as I have a basement full of stuff in questionable order.

Could you explain a bit more? If a box in the basement box is marked with 4 emoticons, how does this help you understand content, context, history of it?

high_priest 2 days ago | parent [-]

I can imagine a QR generator for "obsidian://" links, which would open tagged locations, could be very useful, to identify contents of boxes without opening them.

If the codes are written by hand, then typing them into UI and manually searching for them could be tedious.

---

Emojis/Random Images on boxes, could be used to quickly, visually find the right box in a sea of identical gray boxes.

varun_ch 2 days ago | parent | prev | next [-]

This would be even cooler if there was some heuristic to prefer codes based off of the titles somehow. Like if math-5/limits could somehow get the code M5-LM. I wonder if this is even possible to implement consistently at all. Sounds like a fun problem to solve (it’s the kind of thing an LLM could probably do very inefficiently)

Orange1688 2 days ago | parent | next [-]

Could probably be done by using the path of your note. You could manually specify the code for directories (such as M5 for math-5) and subsequent codes could be based on that. Your code would then be {dir code}-{random letters original to the note}.

Directory codes could also be nested with this

Ezhik 2 days ago | parent | prev [-]

I think Obsidian's fuzzy search already kind of works like that, but that's a really cool idea for generating codes.

link0php 2 days ago | parent | prev | next [-]

So, the hash of the notes path is taken, if I move the note, does it get a new code, and does the code get updated in all the references?

If not, what if I make another note with the same name after moving the original one, does it then become a collision?

vunderba 2 days ago | parent [-]

Yep - and since the stated use case is letting you "quickly reference notes in your vault from other places such as hand-written notes." - the second you re-organize or move a note, all those codes scattered across computers and other mediums are permanently invalid with basically no practical means of automating referential shortcode updates so that's "fun".

I'm a very heavy daily user of Obsidian with about 8000+ personal notes organized across a fairly deep nested folder structure and can't envision a situation where I'd need something like this.

Littering my publicly accessible papers / blogs / etc. with highly idiosyncratic Obsidian shortcodes that only I have the means to access seems of limited use.

Hopefully the author will write another post going into specific use-cases for this extension.

Ezhik 2 days ago | parent [-]

(developer here)

Thanks for the feedback! I guess this plugin is a bit specific to how I use Obsidian [1], as I don't rename my notes quite as often as others do.

As I mentioned in the post, my main use case is being able to quickly reference notes in my hand-written journal. I've also used it a few times in some personal shell scripts.

Probably not a very useful plugin if you already live entirely in your Obsidian vault, though - in there good old [[wiki links]] are much more useful.

I've left a few comments so far on the rename problem, but yeah, it's a hard one to solve. I'll try to think of ways to improve it.

[1]: https://ezhik.jp/hypertext-maximalism/

IncandescentGas a day ago | parent [-]

Would you consider renaming the note to contain a reference to the generated code? Such as "Thoughts on Hedgehogs.md" becomes "Thoughts on Hedgehogs [AB-99].md"

This preserves your goal of having the system rightfully not need another source of truth outside the markdown files, but also lets the markdown file carry the identifier across renames without adding a YAML block.

And it lets you find the note in the "open note" dialog box by typing the code, so no other kind of search interface is needed. Or even to find the note with any other filesystem utility if you have your reference code.

Were you inspired by the Zettelkasten Method for your plugin?

Ezhik a day ago | parent [-]

Hmm... Not a fan of that approach. Would mess things up for my personal use case, at least, making the names less nice. I'm leaning on having some sort of a vault-specific database tracking existing codes across renames as an addition to the existing mechanism. I actually do like the idea of adding tags in the frontmatter, but then it'd become impossible to tag files and folders.

If only we had resource forks.

As for inspiration, I'm not really much of a note-taking system person. My system is just hyperlinking lots of notes together: https://ezhik.jp/hypertext-maximalism/ - this little plugin just helps with that outside of my vault.

quantike 2 days ago | parent | prev | next [-]

Looks like a cool extension thought I'd love some more detail on why someone would use note codes? What do you use them for?

politelemon 2 days ago | parent | next [-]

I was hoping to see the same. As I understand this, it would lock the notes to obsidian only, instead of being somewhat agnostic to the note taker medium.

Ezhik 2 days ago | parent | next [-]

(developer here)

I specifically tried to make this mostly Obsidian-agnostic - the algorithm to generate these note codes is very simple and only requires the note's path relative to the vault.

Here's the whole algorithm in Python:

    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:]}"
obshasaliases 2 days ago | parent | prev [-]

Plus, Obsidian kind of already has this functionality. You can give any note an alias, and all linking to that alias will instead link to the note. So if you're not worried about being agnostic, and unless if you want to mark every single note, I still don't see the point. And even then, even assuming that you do want every note with a code alias, you can just set it up on a template.

Orange1688 2 days ago | parent | prev | next [-]

Per the blog post

>Those codes let you quickly reference notes in your vault from other places such as hand-written notes.

elAhmo 2 days ago | parent | next [-]

Sounds like the same could be done with a slightly longer, but far more readable date + sequential identifier. Such as `YY-xxx` or `YYMM-xxx`.

medstrom 2 days ago | parent [-]

Or just YYMMDD, since there's typically not all that many things you create in one day, so you can just browse among the search hits and it'll be obvious which of the hits you had in mind.

thek3nger 2 days ago | parent | prev [-]

This looks fine, but then if I rename the note, the code changes, invalidating all the hand-written notes links. So it feels unpractical. I would still prefer to encode the creation timestamp and put it in the title/filename/property. At least this would be fixed.

Ezhik 2 days ago | parent | prev | next [-]

(developer here)

I'm too lazy to write full note titles in my paper journals. With this, I can instead write a 4-character code that I can quickly look up in my Obsidian vault.

bfg_9k 2 days ago | parent | prev | next [-]

Yeah I'm not really understanding what it does above and beyond the existing linking system, besides serializing the notes.

hn_throw2025 2 days ago | parent [-]

Plus, the existing linking system allows you to link to a particular heading within an existing note.

From memory… you begin with typing [[ to start the incremental autocomplete on note filename, then when the desired one is top of the list, press # to select a section based on heading.

majkinetor 2 days ago | parent | prev [-]

Its just very short unique id for your note. Practicality.

usiusi 2 days ago | parent | prev | next [-]

Could there be an option to make the code be generated based on the note UUID or creation timestamp so that is is hard-linked to the note and won’t change when the path changes? Because some users want the freedom to update the note title freely without the code breaking.

Igrom 2 days ago | parent | prev | next [-]

In Git, you can typically refer to commits by the shortest unique prefix of their SHA256 hash. So, instead of eb137af21, you can typically write:

> eb137

and IIRC git will raise an error if the prefix is ambiguous. OP, maybe you could do the same?

Ezhik 2 days ago | parent | next [-]

(developer here)

I think ambiguity is not as critical as in Git here - if you look up a note code with multiple entries, it should just show you both so you can choose the right one based on context.

bastih 2 days ago | parent | prev [-]

But that will make links unstable - or OP needs to to turn ambiguous links into some dispatching view.

edejong 2 days ago | parent | prev | next [-]

The OP may find the Wikipedia article on the birthday paradox helpful.

yyx 2 days ago | parent | prev | next [-]

Why? You can already link notes: obsidian://open?vault=Documents&file=Ideas

knubie 2 days ago | parent [-]

I only had to read three sentences into to find your answer:

> Those codes let you quickly reference notes in your vault from other places such as hand-written notes.

yyx 2 days ago | parent [-]

Oh, I thought it meant written in the Notes app. I guess it's nice for those, who don't use johnny decimal system.

precompute 2 days ago | parent | prev | next [-]

So this is just org-id?

kuil009 2 days ago | parent | prev | next [-]

I love this idea. :)

4b11b4 a day ago | parent | prev | next [-]

...haven't you heard of roam.

ftchd 2 days ago | parent | prev | next [-]

[dead]

GlacierFox 2 days ago | parent | prev [-]

This has inspired me to literally build an exact copy of this but use a GUID instead and also not confusingly tie it to the file name. Such weird choice made with this...

Ezhik a day ago | parent [-]

(developer here)

Let me know how your version goes - would love to see it.