I think this very much depends on why you need a unique digital identifier. Timestamps can change, inodes can change, changes can change, MAC addresses can change. (However, +1 for duskwuff)
In some scenarios, you can simply create a table where each path you add gets a new unique number, just like the numeric key columns in a database.
Although hashes can collide, in every real environment this is absolutely unlikely (unless you use the most deceitful algorithm around ...) Most likely, you get errors due to flaws in your implementation, for example, you handle "/ tmp" differently than "/ tmp /" because you do not normalize the paths before hashing them. Or you want to distinguish physical folders, but forget to check the links to hard links and symbolic links to the same folder, this way you will get several hashes / id for the same directory.
Again, depending on your usecase, the collision is not necessarily fatal: if you find that the new path leads to the same hash as the existing one (will not happen!), You can still respond to this case. (*)
Just to help your imagination: if you use a 64-bit hash, you can fill up 150,000,000 1 TB hard drives with empty folders (nothing but short folder names), and then you will have a collision for sure. If you think that it is too risky (blinking, blinking), use a 128-bit hash, which makes it 18,446,744,073,710,000 times less likely.
Hashes are designed to make collisions unlikely, and even the good old MD5 will do its job well if no one willingly tries to create a collision.
(*) Edit: In this article, you see that a collision means that the search is no longer O (1), but a bit slower. Since this rarely happens, you can easily live with it. If you use std :: map (no hash) or std :: hashmap, you do not have to worry about collisions. See what is the difference between a map and a hashmap in STL .