As developers, we often deal with integer IDs in our databases. They are simple, efficient, and great for internal use. But what happens when you expose these IDs to the outside world? A URL like your-app.com/post/1
followed by your-app.com/post/2
can give away a lot of information. It reveals the total number of posts, the rate at which new posts are created, and can even make it easier for malicious actors to scrape your data.
Where to Find Obfuskey
You can find the full source code, documentation, and open an issue on the project's GitHub repository. Obfuskey on GitHub
The Ecosystem of Reversible Obfuscation
Exposing a sequential primary key is a common practice, but it's not without its drawbacks. When choosing a solution to obfuscate these IDs, developers often consider a few popular options. Here’s a look at how Obfuskey compares to some of the key players in the Python ecosystem.
Alternative | How it Works | Pros | Cons |
---|---|---|---|
Hashids | Creates short, unique strings from integers based on a salt and alphabet. | Keys are short, non-sequential, and human-friendly. | Output length can vary with input magnitude. Less precise control over key length. |
Sqids | A modern, flexible alternative to Hashids for obfuscating multiple numbers. | Keys are often shorter, more random-looking, and avoid separator characters. | Also has variable output length depending on input magnitude. |
ShortUUID | Creates short, URL-safe versions of standard UUIDs. | Keys are guaranteed to be unique and short. Great for shortening existing UUIDs. | Not designed for obfuscating sequential integers; it shortens UUIDs, which are already non-sequential. |
Obfuskey | Reversible, non-cryptographic obfuscation of integers using a custom alphabet and fixed length. | Reversible without a database lookup. Keys have a guaranteed fixed length. Full control over the character set. | Not a cryptographic tool; should not be used for security-sensitive data. |
Why Choose Obfuskey?
Obfuskey stands out for its clear API, precise control over a fixed-length output, and a core focus on reversible obfuscation. It provides a simple, robust solution without the overhead of more complex cryptographic or hashing libraries.
Getting Started with Obfuskey
First, let's install the library.
pip install obfuskey
Now, let's see it in action. The core of Obfuskey is the Obfuskey
class. When you instantiate it, you can specify the alphabet of characters to use and the desired key length.
For our first example, let's use the BASE56
alphabet, which is designed to be URL-safe and human-friendly by avoiding characters that can be easily confused, like 0
and O
, or 1
and l
.
from obfuskey import Obfuskey, alphabets
# Initialize Obfuskey with the BASE56 alphabet and a key length of 8
obfuscator = Obfuskey(alphabets.BASE56, key_length=8)
# Let's obfuscate an integer ID
original_id = 1234567890
obfuscated_key = obfuscator.get_key(original_id)
print(f"Original ID: {original_id}") # 1234567890
print(f"Obfuscated Key: {obfuscated_key}") # SdkkpiUc
# Now, let's reverse the process
retrieved_id = obfuscator.get_value(obfuscated_key)
print(f"Retrieved ID: {retrieved_id}") # 1234567890
# Let's see what happens with a different ID
another_id = 1234567891
another_key = obfuscator.get_key(another_id)
print(f"Another ID: {another_id}") # 1234567891
print(f"Another Key: {another_key}") # 5FvRbydm
Notice how obfuscated_key
and another_key
are completely different, even though the original IDs are sequential. This is because Obfuskey uses a randomized mapping to ensure sequential inputs produce non-sequential outputs.
Customizing Your Obfuscation with Different Alphabets
Obfuskey provides several predefined alphabets for different use cases. You can choose one that best fits your needs, from short and compact to fully URL-safe.
For a very compact key that's perfect for internal APIs or systems where readability isn't a concern, you might use BASE64_URL_SAFE
.
# Using a URL-safe Base64 alphabet for a shorter, more compact key
from obfuskey import Obfuskey, alphabets
compact_obfuscator = Obfuskey(alphabets.BASE64_URL_SAFE, key_length=6)
compact_key = compact_obfuscator.get_key(1001)
print(f"Compact Key (Base64): {compact_key}") # fkhvWj
compact_value = compact_obfuscator.get_value(compact_key)
print(f"Original Value: {compact_value}") # 1001
You can even create your own custom alphabet to perfectly match your brand or application's needs. The key is that every character in your custom alphabet must be unique, just like the digits in a number system.
# A custom alphabet using only a unique set of memorable characters
from obfuskey import Obfuskey
custom_alphabet = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefgh" # A unique 44-character alphabet
custom_obfuscator = Obfuskey(custom_alphabet, key_length=10)
custom_key = custom_obfuscator.get_key(987654321)
print(f"Custom Key: {custom_key}") # MQ6gA5LPTT
custom_value = custom_obfuscator.get_value(custom_key)
print(f"Original Value: {custom_value}") # 987654321
This level of customization gives you full control over the appearance and predictability of your obfuscated keys, allowing you to tailor them exactly to your use case.
Conclusion
The Obfuskey
class is a powerful tool for obscuring sequential integer IDs into reversible, non-predictable keys. This simple pattern can dramatically improve the aesthetics and security-by-obscurity of your application's URLs and identifiers.
In the next article, we'll dive into an even more powerful feature of this package: Obfusbit
, which allows you to pack multiple values into a single key, including large numbers like UUIDs.
Top comments (0)