1

I have string and there is 0x80 in it. string presentation is : serialno� and hex presentation is 73 65 72 69 61 6C 6E 6F 80. I want to remove 0x80 from string without convert string to hex string. is it possible in java ? I tried lastIndexOf(0x80). but it returns -1.

my code is (also you can find on https://ideone.com/3p8wKT) :

public static void main(String[] args) {

    String hexValue = "73657269616C6E6F80";
    String binValue = hexStringToBin(hexValue);
    System.out.println("binValue : " + binValue);

    int index = binValue.lastIndexOf(0x80);

    System.out.println("index : " + index);
}

public static String hexStringToBin(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
    }
    return new String(data);
}
3
  • "and hex presentation is" - how have you determined that? Please provide a minimal reproducible example. I suspect your string actually contains U+FFFD, the Unicode replacement character, but it's not certain at the moment. Additionally, it may well be better to clean the data earlier, before converting it to a string. Commented Mar 22, 2018 at 9:56
  • 1
    You should probably us a charset when you return new String(data); You have some bytes and they'll get translated into characters which could have a different value than the raw byte value. Commented Mar 22, 2018 at 10:35
  • General comment: don't try to create a string like this to represent arbitrary binary data. That's not what it's there for. I'd expect a hexStringToBin method to return a byte[], not a String. Commented Mar 22, 2018 at 11:19

3 Answers 3

2

Change your hex string method to map directly to characters.

char[] data = new char[len / 2];
for (int i = 0; i < len; i += 2) {
    data[i / 2] = (char) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
}

return new String(data);

The exchange between a String and byte[] requires an encoding.

Your hex string seems to be a string representation of bytes/characters. It would appear you had an original String -> converted it to your hex string, but we don't know the encoding.

If you want to say that each pair of characters maps to the corresponding character, eg "80" -> char c = 0x80; Then you can achieve that by using a char[], which doesn't get encoded/decoded when creating a string.

If you use a byte[] (as you have done in your example), then it will get decoded and invalid characters get mapped to 0xFFFD, which is unicode replacement character.

Sign up to request clarification or add additional context in comments.

Comments

1

It's because you converted symbol to hex incorrectly (0x80). 1 symbol in UTF-8 can take 1 byte or more. In your case symbol takes 2 bytes and have the following representation 65533 or 0xFFFD. So, if you replace your code with

int index = variable.lastIndexOf(0xFFFD);
//index will be 8

all will work fine.

Code snippet to proof my words:

String variable = "serialno�";
for (char c : variable.toCharArray())
    System.out.print(((int)c)+ " ");
// 115 101 114 105 97 108 110 111 65533

UPDATE

You've made a mistake in hexStringToBin function. Replace it with

public static String hexStringToBin(String s) {
    int len = s.length();
    char[] data = new char[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (char) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
    }

    return new String(data);
}

and all will work fine.

2 Comments

I tried it for other two bytes variables like 0x81,0x82... all is represent as 65533. but i am looking for only 0x80
@user4757345 it is because the charset you are using to create the string maps all of those values to an invalid character.
0

This is working for me :

int hex = 0x6F;
System.out.println("serialno€".lastIndexOf((char)hex));

Output :

7

1 Comment

in char 0x80 is unknown in ASCII table could you tell me which encoding it is ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.