'org.apache.commons.codec.DecoderException: Odd number of characters

Sending hex string in url parameter and trying to convert it in to string at server side. Converting user input string by using following javascript encoding code

function encode(string) {
    var number = "";
    var length = string.trim().length;
    string = string.trim();
    for (var i = 0; i < length; i++) {
        number += string.charCodeAt(i).toString(16);
    }
    return number;
}

Now I'm trying to parse hex string 419 for russian character Й in java code as follows

byte[] bytes = "".getBytes();
     
try {
    bytes = Hex.decodeHex(hex.toCharArray());
    sb.append(new String(bytes,"UTF-8"));
} catch (DecoderException e) {      
    e.printStackTrace(); // Here it gives error 'Odd number of characters'
} catch (UnsupportedEncodingException e) {           
    e.printStackTrace();
}

but it gives following error

"org.apache.commons.codec.DecoderException: Odd number of characters." 

How it can be resolved. As there are many russian character have hex code 3 digit and due to this it is not able to convert it to .toCharArray().



Solution 1:[1]

Use Base64 instead

val aes = KeyGenerator.getInstance("AES")
aes.init(128)
val secretKeySpec = aes.generateKey()
val base64 = Base64.encodeToString(secretKeySpec.encoded, 0)
val bytes = Base64.decode(base64, 0)
SecretKeySpec(bytes, 0, bytes.size, "AES") == secretKeySpec

Solution 2:[2]

In the case you mentioned ? is U+0419 and most cyrillic characters start with a leading 0. This apparently means that adding a 0 before odd numbered character arrays before converting would help.

Testing the javascript seems that this could be safe only for 1 letter long strings: ?(U+0403) returned 403, ?(U+0405) returned 405, but ?? returned 403405 instead of 04030405 or 4030405, which is even worse, becouse it is even and would not trigger the exception and could decode to something completely different.

This question dealing with padding with leading zeros may help with the javascript part.

Solution 3:[3]

Instead of

    sb.append(new String(bytes,"UTF-8"));

Try this

    sb.append(new String(bytes,"Windows-1251"));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Abhinav Atul
Solution 2
Solution 3 Fabio says Reinstate Monica