Encode String of 20 characters to 8 characters, and Decode it back - encryption

I want to know a way to encode a Plain Text of 20 characters to a Cipher of 8 characters and Decode it back to 20 characters.
The possible constituent characters are :
Like how in HexaDecimal number, the characters ranges from '0 to F', for our PlainText it ranges from '0 - A' (base 11).
The required Cipher can have combination of letters and numbers only. It should not have symbols in it.
I want a compression technique or even a program would be more helpful to both encode and decode the above requirements.
Thank You!

I think it's impossible.
11^20 (672749994932560009201) is too bigger than 36^8 (2821109907456).
(11 means count of '0-A', 36 means count of 'A-Z' & '0-9').
At least 238469969 (11^20/36^8) of the plan texts will be encoded as the same output.

Related

How to encrypt 30 digit number into 10 digit number?

Is possible encrypt 30 digit number into 10 digit number, i have number like
23456-32431-23233-76543-98756-54543 i need look like 10 digit encrypt format.
Is possible encrypt 30 digit number into 10 digit number,
Purely mathematically - you cannot. Still we are assuming you want to represent 30 decimal digits of any value using 10 decimal digits. You simply want to put a pint into a shot glass.
Anything, i need compressed the digit.
Compression would be possible if some of the stated assumptions would be not valid.
If you could represent the output as text (any character or binary), you could encode the decimal value to binary/base64 form which would allow shorten representation (still no to 1:3 ratio)
Compression would work well, if the input values (or part of the input) would not be random. If digits or significant part of the input have not uniform distribution or part of the input would represent a limited counter, then the parts or digits could be represented with limited number of bits.
You may know more about your data, so only you could tell anything about the data distribution.
curiosity, how goo.gl & bit.ly working?
The "shortening" sites are a key-value storage, mapping a generated short value to stored full url. So it's mapping, not any compression.

Is it possible to ensure that strings encrypted with AES128/CBC/PKCS5Padding never have trailing equals characters

Is there a deterministic way to ensure that any encrypted/encoded String created with AES128/CBC/PKCS5Padding never has '=' characters padding the end?
Given a crypto util which is a black-box:
String originalValue = "this is a test";
String encryptedValue = TheCryptoUtil.encrypt(original);
The encryptedValue will often look like:
R2gDfGwGvkqZWHH4UF81rg==
Is there a way of varying "originalValue" e.g. by padding the input with whitespaces, such that, regardless of the keys used by TheCryptoUtil, the output will not have any "=" at the end?
Yes, it is possible. I have no idea why you want to do this, but it is possible. Things to keep in mind:
The output of AES-128 with PKCS5Padding will always be some multiple of 16. That is, len(ciphertext) % 16 == 0.
The equals signs that you see on the end of the ciphertext have nothing to do with AES. They are actually base64 padding.
Base64 takes, as input, blocks of 3 bytes and converts them into blocks of 4 characters, where these output 4 characters are any of the 64 defined characters.
This means that the number of bytes of output determines whether or not the base64 of the output will have padding. For example, if you encrypt the message The quick brown fox jumps over the lazy dog., I'd say it is fairly likely (depending on your "black box encryption") that the result will not have any base64 padding.
So, the fact that base64 always produces an encoded string of length that is divisible by 4 means that we can easily determine that length of the original with or without padding. In fact, base64 padding is only part of the spec to help with concatenation issues.
I expect you'll be able to figure out the rest from here!
Luke's answer is correct to say that AES has nothing to do with the padding, it is however missing some of the information below.
Base 64 usually produces padding if the input is not dividable by 3. The padding is just there to make sure that the output only consists of blocks of 4 characters from the base 64 alphabet. Base 64 encodes 64 values or 6 bits per character. 3 bytes are 24 bits, which is dividable by 6 giving you 4 characters required.
The naive thing to do would be to adjust the AES output so that it is dividable by 3. This can however require up to 34 additional padding bytes on the input of AES/CBC/PKCS5Padding, which is stupidity at best.
Not all base 64 schemes actually use padding, so the easiest way of accomplishing this is simply to select a base 64 scheme that doesn't perform the padding at all. Java for instance has a withoutPadding() configuration method.
If the base 64 encoder cannot handle that then it is possible to simply remove the padding after it has been generated. Before decoding you can add back one or two '=' characters until you count a number of base 64 characters (excluding whitespace, see notes) that is dividable by 4.
Note that base 64 usually also uses / and + in the alphabet (there are only 2 * 26 + 10 = 62 characters if you use upper-/lowercase chars & digits). You could look up a URL-safe base 64 encoding - called base64url - if that is what you are after.
Base64 for MIME may also use spaces and end-of-line characters, by the way.

number base decoded message

I have this piece of decoded message, it's a homework but i can't solve it, the message is
IZWGCZZ2EBAUWRSVOJAU45DSOVCEOZKS
N5CHKQLSM5GGSQ2VNVIECUSEIU======
there is a hint saying The string is encoded using an unusual number base. The numbers 2 - 7 are represented and the letters A - Z are represented.
i have looked into the internet but i couldn't find anything, please if anyone could help understand this problem and solve it i would appreciate it
Let's see: A-Z + 2-7 = 32 possible values.
32 values can be contained in 5 bits, thus each byte of the message represents 5 bits.
To decode, each of those 5 bits have to be put together in one long bit-string which is then read as an 8 bit ASCII string.
Or, in other words: Base32 encoding.
So:
IZWGCZZ2EBAUWRSVOJAU45DSOVCEOZKSN5CHKQLSM5GGSQ2VNVIECUSEIU======
converts to:
Flag: AKFUrANtruDGeRoDuArgLiCUmPARDE
See here to test the decoding.

RSA on ASCII message problems with '\0'

I want to encrypt and decrypt ASCII messages using an RSA algorithm written in assembly.
I read that for security and efficiency reasons the encryption is normally not called character-wise but a number of characters is grouped and encrypted together (e.g. wikipedia says that 3 chars are grouped).
Let us assume that we want to encrypt the message "aaa" grouping 2 characters.
"aaa" is stored as 61616100.
If we group two characters and encrypt the resulting halfwords the result for the 6161 block can in fact be something like 0053. This will result in an artificial second '\0' character which corrupts the resulting message.
Is there any way to work around this problem?
Using padding or anything similar is unfortunately not an option since I am required to use the same function for encrypting and decrypting.
The output of RSA is a number. Usually this number is encoded as an octet string (or byte array). You should not treat the result as a character string. You need to treat it as a byte array with the same length as the modulus (or at least the length of the modulus in bytes).
Besides the result containing a zero (null-terminator) the characters may have any value, including non-printable characters such as control characters and 7F. If you want to treat the result as a printable string, convert to hex or base64.

How to encode a large number (in an URL)?

Quite often one has to encode an big (e.g. 128 or 160 bits) number in an url. For example many web applications use md5(random()) for UUIDs.
If you need to put that value in an URL the common approach is to just encode it as an hexadecimal string.
But obviously hex encoding is not a very tight encoding. What other approaches are there which fit nicely in an URL?
I would use The "URL and Filename safe" Base 64 Alphabet.
Base 64 uses two character sets.
Data: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
URLs: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
To use base 64 you need to pad your value to be a multiple of 3 bytes long (24 bits) then split those 24 bits into 4 6bit bytes. Each 6bit value is looked up by position in the string I gave above.
If it all goes well, your final base64 value will always be a multiple of 4 characters long and decode back to a multiple of 3 (8bit) bytes long.
Depending on the language you are using, a lot of them have built in encode and decode functions.
You can do even better with base64-url encoding (a-z, A-Z, 0-9, - and _ [see RFC4648 Section 5]). RFC4648 covers a number of different encoding methods (base16, base32, and base64) an a couple of variants. Also depending on the sparsity of the bits that are set in the number you could conceivably run it through gzip and then use one of the described encoding methods. Of course use of gzip really depends on how large the number you are going to be encoding is.
If you want it tight you can use a base-36 encoding (from 0 to Z).
Using the hint of base36 I currently use something like this (in Python):
>>> str(base64.b32encode(uuid.uuid1().bytes).rstrip('='))
'MTB2ONDSL3YWJN3CA6XIG7O4HM'
Just use hex. Even if you were to get 8 bits per character you're still using a 16-20 character random sequence, which nobody will want to type or say. If you can't put up a short identifier, work on your search capabilities.

Resources