6

I'm trying to shorten UUID values (stored in DB as UUID, not string) to be embedded in URLs. I'm aware of Base64 for URL, but trying to see if I can make it without dash and underscore characters. So I would like to convert UUID to base62. After a lot of googling I found:

  1. There's not a standard for this (something like RFC2045), am I right?

  2. Most importantly there's no proper implementation for it. I found a lot of snippets on how to do it, but with some sort of note that "this is a naive implementation" or something. Is there a proper implementation (I don't mind the exact interpretation how the mapping should be done as long as it's done properly)?

  3. There are some base classes in Apache Commons Codec and Guava which are extended for Base32 and Base64, but I didn't find it easy to extend it for Base62. Is it even possible to do it (considering the fact that the mapping is fundamentally different)?
    Thanks.

MariuszS
  • 30,646
  • 12
  • 114
  • 155
Rad
  • 4,292
  • 8
  • 33
  • 71
  • 1
    mime base64 does not use dash or underscore – Iłya Bursov Sep 19 '18 at 22:05
  • @IłyaBursov MIME Base64 makes it even worth since it needs URL encoding. – Rad Sep 19 '18 at 22:09
  • 1
    @RusselYang dash and underscore don't need escaping, am I missing something? – Rad Sep 19 '18 at 22:11
  • @Rad. you are right. then why not just base64, you can include raw UUID string too. – Russel Yang Sep 19 '18 at 22:12
  • @Rad not really, both `+` and `/` are allowed in URLs, so you might need correct decoding, to avoid conversion – Iłya Bursov Sep 19 '18 at 22:13
  • You're probably better off using the standard Base64Url encoding -- this is exactly what it was designed for. – dnault Sep 19 '18 at 22:15
  • @IłyaBursov I'm not following, `/` must be encoded in the URL, right? that's why we have `Base64Url`. I don't like to have anything other than alphanumeric, let alone slash (`foo/bar` -> `foo%2Fbar`) – Rad Sep 19 '18 at 22:18
  • @Rad no, look at your browser - it has unescaped slashes `https://stackoverflow.com/questions/52414740/encoding-uuid-to-base62-in-java` – Iłya Bursov Sep 19 '18 at 22:20
  • @IłyaBursov, yes but then how can I extract the `{user-id}` segment from `/users/foo/bar` (URL template: `/users/{user-id}`)? (Even if it's possible seems really weird to me, no?) – Rad Sep 19 '18 at 22:27
  • @Rad something like `rawUrl.substring(rawUrl.indexOf("/user/"))` will give you string back – Iłya Bursov Sep 19 '18 at 22:28
  • quote: Using standard Base64 in URL requires encoding of `+`, `/` and `=` characters into special percent-encoded hexadecimal sequences, which makes the string unnecessarily longer. – Rad Sep 19 '18 at 22:29
  • Yes, but if I were your developer and came to you with that code in my spring application what would be your reaction? :D – Rad Sep 19 '18 at 22:31
  • @Rad it is true _only_ if you're using `/` as special delimiter (which a lot of systems do), but you can parse raw url by yourself – Iłya Bursov Sep 19 '18 at 22:31
  • Yes, got your point. – Rad Sep 19 '18 at 22:31
  • @Rad my reaction would be `oh, they're trying to optimize size of the url and they avoid unneeded parsing, which is faster, cool` :) – Iłya Bursov Sep 19 '18 at 22:32
  • @IłyaBursov then I'd love to work in your team :) – Rad Sep 19 '18 at 22:40

2 Answers2

6

You might want to try this library: https://github.com/Devskiller/friendly-id

The FriendlyID library converts a given UUID (with 36 characters) to a URL-friendly ID (a "FriendlyID") which is based on Base62 (with a maximum of 22 characters), as in the example below:

   UUID                                        Friendly ID
   
   c3587ec5-0976-497f-8374-61e0c2ea3da5   ->   5wbwf6yUxVBcr48AMbz9cb
   |                                           |                              
   36 characters                               22 characters or less

In addition, this library allows to:

  • convert from a FriendlyID back to the original UUID; and
  • create a new, random FriendlyID
Community
  • 1
  • 1
user3078523
  • 1,520
  • 18
  • 27
  • 1
    I'm pretty sure I had found this lib at the time, but can't recall why I didn't use it. – Rad Aug 22 '19 at 07:45
  • Quick warning about FriendlyID vs. other Base62 libs: FriendlyID uses inversed letter case compared to standard Base62. Its alphabet is 0123456789ABC...abc... and not the standard 0123456789abc...ABC... – Alessandro May 05 '23 at 09:01
0

Base62Codec can encode UUIDs efficiently to base-62.

Base62Codec codec = new Base62Codec();
String string = codec.encode(uuid);

Or:

String string = Base62Codec.INSTANCE.encode(uuid);

There are codecs for other encodings in the same package of uuid-creator.

fabiolimace
  • 972
  • 11
  • 13