最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - org.apache.commons.codec.DecoderException: Odd number of characters - Stack Overflow

programmeradmin2浏览0评论

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.apachemons.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().

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().

Share Improve this question edited Jun 21, 2023 at 2:53 Olaf Kock 48.1k9 gold badges62 silver badges91 bronze badges asked Jan 12, 2015 at 14:46 Rahul PRahul P 1,1033 gold badges17 silver badges32 bronze badges 1
  • Have you tried encodeURI() on JS side and use on Java side normally? – Aakash Commented Dec 13, 2023 at 10:08
Add a comment  | 

5 Answers 5

Reset to default 0

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

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.

Hi you can use Unicode encoding. In your case, char Й will be converted to \u0419 in the client side. Then in the server side you can use Java like:

import org.apache.commons.lang.StringEscapeUtils;

// Russian char = "Й"
String hex = "\u0419";
String unescapeJava = StringEscapeUtils.unescapeJava(hex);

System.out.println("unescapeJava => " + unescapeJava);

The problem is in this line:

number += string.charCodeAt(i).toString(16);

When the loop reaches the character 'Й', string.charCodeAt(i) returns 1049 in decimal base, but when you convert it to hex (base 16), it becomes '419' and you append that directly. Appending the char code up to 0x80 happens to be correct, but it's not correct beyond this point. What you want to append in this case is the 2-byte encoding for characters according to the UTF-8 specification. In wikipedia there's a good summary and a few examples of how to properly encode text in UTF-8: https://en.wikipedia.org/wiki/UTF-8

This link explains how to get a UTF-8 byte array from a string in js: How to convert UTF8 string to byte array?

Instead of

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

Try this

    sb.append(new String(bytes,"Windows-1251"));
发布评论

评论列表(0)

  1. 暂无评论