Why does this code return 221 here? What is the logic behind this? How this working? Please explain this to me for I am new to Java.
import java.io.UnsupportedEncodingException;
public class Checksrting {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
byte[] byteArray = new byte[2];
byteArray[0] = 100;
byteArray[1] = 100;
Long ID = null;
try {
ID = Long.parseLong(new String(byteArray, "utf-8").trim(), 16);
System.out.print(ID);
} catch (NumberFormatException | UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So please explain to me what is the use of utf-8 and ,16?
100 is the equivalent of the d character. So your string will become dd.
When you do
ID = Long.parseLong(new String(byteArray, "utf-8").trim(), 16);
You are converting the string to a long number, with hexadecimal format.
the decimal value for dd is 221, that's why you get that output.
what is the use of utf-8 and ,16?
utf-8 is the character encoding that the String constructor will use to build up the string, and 16 is the radix that will be used to convert your string to a long.
As you can see in the documentation String constructor gets a parameter charset:
Constructs a new String by decoding the specified array of bytes using the specified charset. The length of the new String is a function of the charset, and hence may not be equal to the length of the byte array.
And the 16 is the radix which is to use for the conversion:
See the documentation from Long
It returns 221 because of the conversion of dd string to hexadecimal number.
new String(byteArray, "utf-8").trim();
With this statement byteArray[0] contains 100 which is converted to character its representation is 'd' as there are 2 elements in the byteArray therefore it creates the String 'dd' and converts the String into the hexadecimal code.
new String(byteArray, "utf-8").trim();
returns 'dd'
then it is parsed into the Long value as the regEx parameter is given 16, therefore it converts into hexadecimal format i.e; 221
Long.parseLong("dd",16);
"utf-8" is the character encoding, i.e. how a String is represented as bytes.
UTF-8 uses a variable length encoding, and ASCII characters can be represented as a single byte with 0 as highest bit. This is the case for d which is represented as 100 (in decimal notation). Since you have 2 bytes with the number 100, this translates to the string "dd"
16 is the radix used for conversion from String to Long, so this translates from strings in hex notation.
A d in hex notation is 13 in decimal notation. So dd becomes 13 * 16 + 13 = 208 + 13 = 221
I agree with the older answers, but am adding some advice on how to figure out this sort of issue.
First, if you are having trouble understanding a complicated expression, extract sub-expressions into local variables, and print those variables:
String s1 = new String(byteArray, "utf-8");
System.out.println("s1: |" + s1 + "|");
String s2 = s1.trim();
System.out.println("s2: |" + s2 + "|");
ID = Long.parseLong(s2, 16);
System.out.print(ID);
It now prints:
s1: |dd|
s2: |dd|
221
Next, look at the individual sub-expressions. If there is anything you do not understand about a call and what it did, look it up in the API documentation.
For example, you asked about the "16". The Long.parseLong(String s, int radix) documentation says: "Parses the string argument as a signed long in the radix specified by the second argument. ". The output from the modified program shows that s is "dd", so it is going to parse "dd" as a hexadecimal number. A programmer's calculator will show you that hex "dd" is decimal 221.
Related
An Item-ID in hexadecimal and the amount in decimal has to be entered in two JTextFields.
Now I have to convert the Item ID hexadecimal encoded in a String to a byte hexadecimal.
String str = itemIdField.getText(); // Would be, for example, "5e"
byte b = // Should be 0x5e then.
So if str = "5e", b = 0x5e
if str = "6b" b = 0x6b and so on.
Does anybody now, what the code to convert that would be then?
Google doesn't know, it thinks, I want to convert the text to a byte[]
Thank you, Richie
You can use Byte.parseByte(str, 16), that will return the byte value represented by the hexadecimal value in str.
If I have some binary data D And I convert it to string S. I expect than on converting it back to binary I will get D. But It's wrong.
public class A {
public static void main(String[] args) throws IOException {
final byte[] bytes = new byte[]{-114, 104, -35};// In hex: 8E 68 DD
System.out.println(bytes.length); //prints 3
System.out.println(new String(bytes, "UTF-8").getBytes("UTF-8").length); //prints 7
}
}
Why does this happens?
Converting between a byte array to a String and back again is not a one-to-one mapping operation. Reading the docs, the String implmentation uses the CharsetDecoder to convert the incoming byte array into unicode. The first and last bytes in your input byte array must not map to a valid unicode character, thus it replaces it with some replacement string.
It's likely that the bytes you're converting to a string don't actually form a valid string. If java can't figure out what you mean by each byte, it will attempt to fix them. This means that when you convert back to the byte array, it won't be the same as when you started. If you try with a valid set of bytes, then you should be more successful.
Your data can't be decoded into valid Unicode characters using UTF-8 encoding. Look at decoded string. It consists of 3 characters: 0xFFFD, 0x0068 and 0xFFFD. First and last are "�" - Unicode replacement characters. I think you need to choose other encoding. I.e. "CP866" produces valid string and converts back into same array.
How can I convert ASCII values to hexadecimal and binary values (not their string representation in ASCII)? For example, how can I convert the decimal value 26 to 0x1A?
So far, I've tried converting using the following steps (see below for actual code):
Converting value to bytes
Converting each byte to int
Converting each int to hex, via String.toString(intValue, radix)
Note: I did ask a related question about writing hex values to a file.
Clojure code:
(apply str
(for [byte (.getBytes value)]
(.replace (format "%2s" (Integer/toString (.intValue byte) 16)) " " "0")))))
Java code:
Byte[] bytes = "26".getBytes();
for (Byte data : bytes) {
System.out.print(String.format("%2s", Integer.toString(data.intValue(), 16)).replace(" ", "0"));
}
System.out.print("\n");
Hexadecimal, decimal, and binary integers are not different things -- there's only one underlying representation of an integer. The one thing you said you're trying to avoid -- "the ASCII string representation" -- is the only thing that's different. The variable is always the same, it's just how you print it that's different.
Now, it's not 100% clear to me what you're trying to do. But given the above, the path is clear: if you've got a String, convert it to an int by parsing (i.e., using Integer.parseInt()). Then if you want it printed in some format, it's easy to print that int as whatever you want using, for example, printf format specifiers.
If you actually want hexadecimal strings, then (format "%02X" n) is much simpler than the hoops you jump through in your first try. If you don't, then just write the integer values to a file directly without trying to convert them to a string.
Something like (.write out (read-string string-representing-a-number)) should be sufficient.
Here are your three steps rolled up into one line of clojure:
(apply str (map #(format "0x%02X " %) (.getBytes (str 42))))
convert to bytes (.getBytes (str 42))
no actual need for step 2
convert each byte to a string of characters representing it in hex
or you can make it look more like your steps with the "thread last" macro
(->> (str 42) ; start with your value
(.getBytes) ; put it in an array of bytes
(map #(format "0x%02X " %)) ; make hex string representation
(apply str)) ; optionally wrap it up in a string
static String decimalToHex(String decimal, int minLength) {
Long n = Long.parseLong(decimal, 10);
// Long.toHexString formats assuming n is unsigned.
String hex = Long.toHexString(Math.abs(n), 16);
StringBuilder sb = new StringBuilder(minLength);
if (n < 0) { sb.append('-'); }
int padding = minLength - hex.length - sb.length();
while (--padding >= 0) { sb.append('0'); }
return sb.append(hex).toString();
}
//get Unicode for char
char theChar = 'a';
//use this to go from i`enter code here`nt to Unicode or HEX or ASCII
int theValue = 26;
String hex = Integer.toHexString(theValue);
while (hex.length() < 4) {
hex = "0" + hex;
}
String unicode = "\\u" + (hex);
System.out.println(hex);
I want to display a Unicode character in Java. If I do this, it works just fine:
String symbol = "\u2202";
symbol is equal to "∂". That's what I want.
The problem is that I know the Unicode number and need to create the Unicode symbol from that. I tried (to me) the obvious thing:
int c = 2202;
String symbol = "\\u" + c;
However, in this case, symbol is equal to "\u2202". That's not what I want.
How can I construct the symbol if I know its Unicode number (but only at run-time---I can't hard-code it in like the first example)?
If you want to get a UTF-16 encoded code unit as a char, you can parse the integer and cast to it as others have suggested.
If you want to support all code points, use Character.toChars(int). This will handle cases where code points cannot fit in a single char value.
Doc says:
Converts the specified character (Unicode code point) to its UTF-16 representation stored in a char array. If the specified code point is a BMP (Basic Multilingual Plane or Plane 0) value, the resulting char array has the same value as codePoint. If the specified code point is a supplementary code point, the resulting char array has the corresponding surrogate pair.
Just cast your int to a char. You can convert that to a String using Character.toString():
String s = Character.toString((char)c);
EDIT:
Just remember that the escape sequences in Java source code (the \u bits) are in HEX, so if you're trying to reproduce an escape sequence, you'll need something like int c = 0x2202.
The other answers here either only support unicode up to U+FFFF (the answers dealing with just one instance of char) or don't tell how to get to the actual symbol (the answers stopping at Character.toChars() or using incorrect method after that), so adding my answer here, too.
To support supplementary code points also, this is what needs to be done:
// this character:
// http://www.isthisthingon.org/unicode/index.php?page=1F&subpage=4&glyph=1F495
// using code points here, not U+n notation
// for equivalence with U+n, below would be 0xnnnn
int codePoint = 128149;
// converting to char[] pair
char[] charPair = Character.toChars(codePoint);
// and to String, containing the character we want
String symbol = new String(charPair);
// we now have str with the desired character as the first item
// confirm that we indeed have character with code point 128149
System.out.println("First code point: " + symbol.codePointAt(0));
I also did a quick test as to which conversion methods work and which don't
int codePoint = 128149;
char[] charPair = Character.toChars(codePoint);
System.out.println(new String(charPair, 0, 2).codePointAt(0)); // 128149, worked
System.out.println(charPair.toString().codePointAt(0)); // 91, didn't work
System.out.println(new String(charPair).codePointAt(0)); // 128149, worked
System.out.println(String.valueOf(codePoint).codePointAt(0)); // 49, didn't work
System.out.println(new String(new int[] {codePoint}, 0, 1).codePointAt(0));
// 128149, worked
--
Note: as #Axel mentioned in the comments, with java 11 there is Character.toString(int codePoint) which would arguably be best suited for the job.
This one worked fine for me.
String cc2 = "2202";
String text2 = String.valueOf(Character.toChars(Integer.parseInt(cc2, 16)));
Now text2 will have ∂.
Remember that char is an integral type, and thus can be given an integer value, as well as a char constant.
char c = 0x2202;//aka 8706 in decimal. \u codepoints are in hex.
String s = String.valueOf(c);
String st="2202";
int cp=Integer.parseInt(st,16);// it convert st into hex number.
char c[]=Character.toChars(cp);
System.out.println(c);// its display the character corresponding to '\u2202'.
Although this is an old question, there is a very easy way to do this in Java 11 which was released today: you can use a new overload of Character.toString():
public static String toString(int codePoint)
Returns a String object representing the specified character (Unicode code point). The result is a string of length 1 or 2, consisting solely of the specified codePoint.
Parameters:
codePoint - the codePoint to be converted
Returns:
the string representation of the specified codePoint
Throws:
IllegalArgumentException - if the specified codePoint is not a valid Unicode code point.
Since:
11
Since this method supports any Unicode code point, the length of the returned String is not necessarily 1.
The code needed for the example given in the question is simply:
int codePoint = '\u2202';
String s = Character.toString(codePoint); // <<< Requires JDK 11 !!!
System.out.println(s); // Prints ∂
This approach offers several advantages:
It works for any Unicode code point rather than just those that can be handled using a char.
It's concise, and it's easy to understand what the code is doing.
It returns the value as a string rather than a char[], which is often what you want. The answer posted by McDowell is appropriate if you want the code point returned as char[].
This is how you do it:
int cc = 0x2202;
char ccc = (char) Integer.parseInt(String.valueOf(cc), 16);
final String text = String.valueOf(ccc);
This solution is by Arne Vajhøj.
The code below will write the 4 unicode chars (represented by decimals) for the word "be" in Japanese. Yes, the verb "be" in Japanese has 4 chars!
The value of characters is in decimal and it has been read into an array of String[] -- using split for instance. If you have Octal or Hex, parseInt take a radix as well.
// pseudo code
// 1. init the String[] containing the 4 unicodes in decima :: intsInStrs
// 2. allocate the proper number of character pairs :: c2s
// 3. Using Integer.parseInt (... with radix or not) get the right int value
// 4. place it in the correct location of in the array of character pairs
// 5. convert c2s[] to String
// 6. print
String[] intsInStrs = {"12354", "12426", "12414", "12377"}; // 1.
char [] c2s = new char [intsInStrs.length * 2]; // 2. two chars per unicode
int ii = 0;
for (String intString : intsInStrs) {
// 3. NB ii*2 because the 16 bit value of Unicode is written in 2 chars
Character.toChars(Integer.parseInt(intsInStrs[ii]), c2s, ii * 2 ); // 3 + 4
++ii; // advance to the next char
}
String symbols = new String(c2s); // 5.
System.out.println("\nLooooonger code point: " + symbols); // 6.
// I tested it in Eclipse and Java 7 and it works. Enjoy
Here is a block to print out unicode chars between \u00c0 to \u00ff:
char[] ca = {'\u00c0'};
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 16; j++) {
String sc = new String(ca);
System.out.print(sc + " ");
ca[0]++;
}
System.out.println();
}
Unfortunatelly, to remove one backlash as mentioned in first comment (newbiedoodle) don't lead to good result. Most (if not all) IDE issues syntax error. The reason is in this, that Java Escaped Unicode format expects syntax "\uXXXX", where XXXX are 4 hexadecimal digits, which are mandatory. Attempts to fold this string from pieces fails. Of course, "\u" is not the same as "\\u". The first syntax means escaped 'u', second means escaped backlash (which is backlash) followed by 'u'. It is strange, that on the Apache pages is presented utility, which doing exactly this behavior. But in reality, it is Escape mimic utility. Apache has some its own utilities (i didn't testet them), which do this work for you. May be, it is still not that, what you want to have. Apache Escape Unicode utilities But this utility 1 have good approach to the solution. With combination described above (MeraNaamJoker). My solution is create this Escaped mimic string and then convert it back to unicode (to avoid real Escaped Unicode restriction). I used it for copying text, so it is possible, that in uencode method will be better to use '\\u' except '\\\\u'. Try it.
/**
* Converts character to the mimic unicode format i.e. '\\u0020'.
*
* This format is the Java source code format.
*
* CharUtils.unicodeEscaped(' ') = "\\u0020"
* CharUtils.unicodeEscaped('A') = "\\u0041"
*
* #param ch the character to convert
* #return is in the mimic of escaped unicode string,
*/
public static String unicodeEscaped(char ch) {
String returnStr;
//String uniTemplate = "\u0000";
final static String charEsc = "\\u";
if (ch < 0x10) {
returnStr = "000" + Integer.toHexString(ch);
}
else if (ch < 0x100) {
returnStr = "00" + Integer.toHexString(ch);
}
else if (ch < 0x1000) {
returnStr = "0" + Integer.toHexString(ch);
}
else
returnStr = "" + Integer.toHexString(ch);
return charEsc + returnStr;
}
/**
* Converts the string from UTF8 to mimic unicode format i.e. '\\u0020'.
* notice: i cannot use real unicode format, because this is immediately translated
* to the character in time of compiling and editor (i.e. netbeans) checking it
* instead reaal unicode format i.e. '\u0020' i using mimic unicode format '\\u0020'
* as a string, but it doesn't gives the same results, of course
*
* This format is the Java source code format.
*
* CharUtils.unicodeEscaped(' ') = "\\u0020"
* CharUtils.unicodeEscaped('A') = "\\u0041"
*
* #param String - nationalString in the UTF8 string to convert
* #return is the string in JAVA unicode mimic escaped
*/
public String encodeStr(String nationalString) throws UnsupportedEncodingException {
String convertedString = "";
for (int i = 0; i < nationalString.length(); i++) {
Character chs = nationalString.charAt(i);
convertedString += unicodeEscaped(chs);
}
return convertedString;
}
/**
* Converts the string from mimic unicode format i.e. '\\u0020' back to UTF8.
*
* This format is the Java source code format.
*
* CharUtils.unicodeEscaped(' ') = "\\u0020"
* CharUtils.unicodeEscaped('A') = "\\u0041"
*
* #param String - nationalString in the JAVA unicode mimic escaped
* #return is the string in UTF8 string
*/
public String uencodeStr(String escapedString) throws UnsupportedEncodingException {
String convertedString = "";
String[] arrStr = escapedString.split("\\\\u");
String str, istr;
for (int i = 1; i < arrStr.length; i++) {
str = arrStr[i];
if (!str.isEmpty()) {
Integer iI = Integer.parseInt(str, 16);
char[] chaCha = Character.toChars(iI);
convertedString += String.valueOf(chaCha);
}
}
return convertedString;
}
char c=(char)0x2202;
String s=""+c;
(ANSWER IS IN DOT NET 4.5 and in java, there must be a similar approach exist)
I am from West Bengal in INDIA.
As I understand your problem is ...
You want to produce similar to ' অ ' (It is a letter in Bengali language)
which has Unicode HEX : 0X0985.
Now if you know this value in respect of your language then how will you produce that language specific Unicode symbol right ?
In Dot Net it is as simple as this :
int c = 0X0985;
string x = Char.ConvertFromUtf32(c);
Now x is your answer.
But this is HEX by HEX convert and sentence to sentence conversion is a work for researchers :P
If I use any ASCII characters from 33 to 127, the codePointAt method gives the correct decimal value, for example:
String s1 = new String("#");
int val = s1.codePointAt(0);
This returns 35 which is the correct value.
But if I try use ASCII characters from 128 to 255 (extended ASCII/ISO-8859-1), this method gives wrong value, for example:
String s1 = new String("ƒ") // Latin small letter f with hook
int val = s1.codePointAt(0);
This should return 159 as per this reference table, but instead returns 409, why is this?
But if I try use ASCII characters from 128 to 255
ASCII doesn't have values in this range. It only uses 7 bits.
Java chars are UTF-16 (and nothing else!). If you want to represent ASCII using Java, you need to use a byte array.
The codePointAt method returns the 32-bit codepoint. 16-bit chars can't contain the entire Unicode range, so some code points must be split across two chars (as per the encoding scheme for UTF-16). The codePointAt method helps resolve to chars code points.
I wrote a rough guide to encoding in Java here.
Java chars are not encoded in ISO-8859-1. They use UTF-16 which has the same values for 7bit ASCII characters (only values from 0-127).
To get the correct value for ISO-8859-1 you have to convert your string into a byte[] with String.getBytes("ISO-8859-1"); and look in the byte array.
Update
ISO-8859-1 is not the extended ASCII encoding, use String.getBytes("Cp437"); to get the correct values.
in Unicode
ƒ 0x0192 LATIN SMALL LETTER F WITH HOOK
String.codePointAt returns the Unicode-Codepoint at this specified index.
The Unicode-Codepoint of ƒ is 402, see
http://www.decodeunicode.org/de/u+0192/properties
So
System.out.println("ƒ".codePointAt(0));
printing 402 is correct.
If you are interested in the representation in other charsets, you can printout the bytes representaion of the character in other charsets via getBytes(String charsetName):
final String s = "ƒ";
for (final String csName : Charset.availableCharsets().keySet()) {
try {
final Charset cs = Charset.forName(csName);
final CharsetEncoder encode = cs.newEncoder();
if (encode.canEncode(s))
{
System.out.println(csName + ": " + Arrays.toString(s.getBytes(csName)));
}
} catch (final UnsupportedOperationException uoe) {
} catch (final UnsupportedEncodingException e) {
}
}