Simple number-to-number (or number-to-hex) encryption algorithm that minimizes # of characters
I need to encrypt a number and I and this encrypted value will be given to a customer ask a key so I want to minimize the number of digits and make them all printable.
So I'd like the result to be either all number or all Hex characters.
The current encryption method I'm using (for non numbers) converts the characters to hex (2 hex digits each). That doubles the number of characters. I also considered just treating the input as hex (so each pair of numbers 开发者_JS百科is treated as a Hex pair, but then you have ambiguity between an input of 0123 and 123 (when decrypting that leading '0' is lost.
Any suggestions?
Don't conflate two different issues. Use any secure encryption algorithm (I recommend AES-256), and then use base64 encoding if the output has to be printable.
If you want to restrict it to another set (e.g. lower-case letters), use the appropriate base (e.g. hexavigesimal)
If the requirement is that you print out a card with the "license key" on it, that they have to manually type in then I think encrypting the required values is not the best solution. There'll just be too much data.
I think a better solution is to use a simple hash algorithm on their username/email address that they've registered with to hash the result to a 128-bit value (16 bytes) and then use Base-32 to convert that into the letters A-Z and digits 2-7 (which would come out at around 26 characters).
Base32 has the advantage that it's not case-sensitive (like base 64 is) and you don't get confusion between "i" and "1" (etc).
I figured out a simple kludge: If the # of digits is odd then I prefix a placeholder Hex(F) character. Then when I decrpypt, if I see that placeholder (F) then I know it was a place holder (b/c only numbers are allowed as input to this function)
It seems that you are confusing encryption and encoding. They are completely separate concerns. Because you don't provide nearly enough information about required security to say anything about appropriate encryption I'll assume that you are talking about encoding. For encoding, it actually doesn't matter if the input is encrypted or not. The only difference is that an encrypted input almost certainly can't be compressed, so any compression should be done before encryption.
For encoding, the simplest approach is to consider the input as a large number (you ), pick a set of symbols and encode the number as base-N where N is the size of the chosen set. Because the resulting code is intended for human entry, you'll want to avoid having multiple characters with similar shapes (1,l,I / o,O,0,D / 5,S), the choice is dependent on the font used.
It's also very useful to have some error detection built in. A simple way to create good error detection is to add some bits of a good hash function to the number. For example (in pseudocode):
number_to_encode = input_number << 5 | MD5(input_number) & 0x1F
encoded_string = Base32Encode(number_to_encode)
number_to_decode = Base32Decode(encoded_string)
output_number = number_to_decode >> 5
checksum = number_to_decode & 0x1F
if MD5(output_number) & 0x1F != checksum then
Error
You can do better than that if you have an error model, but assuming random error model it's as good as it gets, detecting more than 96% of all errors, adding only one base32 character.
精彩评论