I've a String with value 0xE20x800x93.
I try to convert them like this and it works
byte[] bs = new byte[]{
(byte) 0xE2,(byte) 0x80, (byte) 0x93
};
But what I want is without doing the explicit casting, I need to convert it into a byte array.
Or at least a way to convert into a byte object, and not a byte[] object.
You can do it in one (albeit long) line:
byte[] bytes = Arrays.copyOfRange(new ByteBuffer().putInt(Integer.parseInt(str.replace("0x", ""), 16)).array(), 1, 4);
This assumes you have exactly 3 bytes to get. If it's a variable length, the following code is more generic, but slightly more verbose, because it uses the length of the input to determine the eventual result size:
byte[] bytes = Arrays.copyOfRange(new ByteBuffer().putInt(Integer.parseInt(str.replace("0x", ""), 16)).array(), 4 - str.length() / 4, 4);
try DatatypeConverter.parseHexBinary(str) from javax.xml.bind package
Related
For this question I am asked to:
convert text to hash,
then put it into a byte array,
construct a new byte array 0b, with a zero byte at index 0 then b.
I am able to get the hash of the message c84291b88e8367ef3448899117f8b497f58ac7d43689239783f708ea0092c39b with my code:
MessageDigest md = MessageDigest.getInstance("SHA-256");
//Convert Message to hash
md.update(message1.getBytes());
byte[] digest = md.digest();
String Hash = hexaToString(digest);
System.out.println( "Message 1 in hash is = " + Hash);
And I am able to convert it into a byte array but I am not sure how to add the zerobyte to the start of the byte array?
When computing the digest, you can provide an output array via an overloaded form of digest(). You can allocate an extra byte, and store whatever you like in the extra space at the beginning.
int len = md.getDigestLength();
byte[] digest = new byte[len + 1];
md.digest(digest, 1, len);
I have the following values:
public static short TAG_VALUE1 = 0x2E09;
public static short TAG_VALUE2 = 0x2E0D;
And I want to create a byte[] from both values. As a byte array, I have to get the first byte and insert it into the array and then the second byte of each TAG. I tried to convert to string and then go back, but I think it has to be an easier way to do so.
How can I get this in a byte[] that looks like this?
2E 09 2E 0D
How about
byte[] foo = new byte[] {
(byte) (TAG_VALUE1>>8),
(byte) (TAG_VALUE1),
(byte) (TAG_VALUE2>>8),
(byte) (TAG_VALUE2),
};
See ByteBuffer and its many uses.
byte[] bytes = new byte[4];
ByteBuffer buf = ByteBuffer.wrap(bytes);
buf.putShort(TAG_VALUE1);
buf.putShort(TAG_VALUE2);
With the below code snippet given in this link,
byte[] bytes = {0x00, 0x48, 0x00, 0x69, 0x00, 0x2C,
0x60, (byte)0xA8, 0x59, 0x7D, 0x00, 0x21}; // "Hi,您好!"
Charset charset = Charset.forName("UTF-8");
// Encode from UCS-2 to UTF-8
// Create a ByteBuffer by wrapping a byte array
ByteBuffer bb = ByteBuffer.wrap(bytes);
// Create a CharBuffer from a view of this ByteBuffer
CharBuffer cb = bb.asCharBuffer();
Using wrap() method, "The new buffer will be backed by the given byte array", Here we do not have any encoding from byte to other format, it just placed byte array in a buffer.
Can you please help me understand, what exactly are we doing when we say bb.asCharBuffer() in the above code?cb is similar to array of characters. Because char is UTF-16 in Java, Using asCharBuffer() method, Are we considering every 2bytes in bb as char? Is this the right approach? If no, Please help me with right approach.
Edit:
I tried this program as recommended by Meisch below,
byte[] bytes = {0x00, 0x48, 0x00, 0x69, 0x00, 0x2C,
0x60, (byte)0xA8, 0x59, 0x7D, 0x00, 0x21}; // "Hi,您好!"
Charset charset = Charset.forName("UTF-8");
CharsetDecoder decoder = charset.newDecoder();
ByteBuffer bb = ByteBuffer.wrap(bytes);
CharBuffer cb = decoder.decode(bb);
which gives exception
Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(Unknown Source)
at java.nio.charset.CharsetDecoder.decode(Unknown Source)
at TestCharSet.main(TestCharSet.java:16)
Please help me, am stuck up here!!!
Note : am using java 1.6
You ask: “Because char is UTF-16 in Java, using asCharBuffer() method, are we considering every 2 bytes in bb as char?”
The answer to that question is yes. Your understanding is correct.
Your next question is: “Is this the right approach?”
If you are just trying to demonstrate how the ByteBuffer, CharBuffer and Charset classes work, it's acceptable.
However, when you are coding an application, you will never write code like that. To begin with, there is no need for a byte array; you can represent the characters as a literal String:
String s = "Hi,\u60a8\u597d!";
If you want to convert the string to UTF-8 bytes, you can simply do this:
byte[] encodedBytes = s.getBytes(StandardCharsets.UTF_8);
If you're still using Java 6, you would do this instead:
byte[] encodedBytes = s.getBytes("UTF-8");
Update: Your byte array represents chars in the UTF-16BE (big-endian) encoding. Specifically, your array has exactly two bytes per character. That is not a valid UTF-8 encoded byte sequence, which is why you're getting the MalformedInputException.
When characters are encoded as UTF-8 bytes, each character will be represented with 1 to 4 bytes. For your second code fragement to work, the array must be:
byte[] bytes = {
0x48, 0x69, 0x2c, // ASCII chars are 1 byte each
(byte) 0xe6, (byte) 0x82, (byte) 0xa8, // U+60A8
(byte) 0xe5, (byte) 0xa5, (byte) 0xbd, // U+597D
0x21
};
When converting from bytes to chars, my earlier statement still applies: You don't need ByteBuffer or CharBuffer or Charset or CharsetDecoder. You can use those classes, but usually it's more succinct to just create a String:
String s = new String(bytes, "UTF-8");
If you want a CharBuffer, just wrap the String:
CharBuffer cb = CharBuffer.wrap(s);
You may be wondering when it is appropriate to use a CharsetDecoder directly. You would do that if the bytes are coming from a source which is not under your control, and you have good reason to believe it may not contain properly UTF-8 encoded bytes. Using an explicit CharsetDecoder allows you to customize how invalid bytes will be handled.
I just had a look at the sources, it boils down to two bytes from the byte buffer being combined into one character. The order in which the two bytes are used depends on the endianness, default ist big-endian.
Another approach using nio classes than what I wrote in the comments would be to use the CharsetDecoder.decode() method.
Charset charset = Charset.forName("UTF-8");
CharsetDecoder decoder = charset.newDecoder();
ByteBuffer bb = ByteBuffer.wrap(bytes);
CharBuffer cb = decoder.decode(bb);
I need to convert this Python code in Java but the '\x00' hexcode is a real problem.
How can I do the export data to bytes[] ?
message__FirstPart = '\x45\x55\x43\x45\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00'
# event_par = key number (5+ 0..9
message__event_par = chr(key+5)
message__filler = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
# mit link state = 1
message__link_status = chr(int(GroupID))
# mit link state = 1
#message__link_status = '\x01'
# the sender’s mac-address
message__mac = '\x00\x00\x00\x00\x00\x00'
data = message__FirstPart + message__event_par + message__filler + message__link_status + message__mac
Thanks !
Strings in Java are made up of char, not byte. Though a char is really just two bytes, it is interpreted as UTF-16 and this can cause all sorts of trouble when you really want to talk about a series of bytes as it appears in your example.
You can express literal bytes as hexadecimal in Java as 0x00, 0x01, ..., 0xFF though these usually get interpreted as int and must be cast to byte:
byte[] arr = new byte[] { (byte) 0x01, (byte) 0x02 };
You can also look into the ByteBuffer class for assembling streams of bytes.
I'm trying to encrypt some integers in java using java.security and javax.crypto.
The problem seems to be that the Cipher class only encrypts byte arrays. I can't directly convert an integer to a byte string (or can I?). What is the best way to do this?
Should I convert the integer to a string and the string to byte[]? This seems too inefficient.
Does anyone know a quick/easy or efficient way to do it?
Please let me know.
Thanks in advance.
jbu
You can turn ints into a byte[] using a DataOutputStream, like this:
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
DataOutputStream dos = new DataOutputStream (baos);
dos.writeInt (i);
byte[] data = baos.toByteArray();
// do encryption
Then to decrypt it later:
byte[] decrypted = decrypt (data);
ByteArrayInputStream bais = new ByteArrayInputStream (data);
DataInputStream dis = new DataInputStream (bais);
int j = dis.readInt();
You can also use BigInteger for conversion:
BigInteger.valueOf(integer).toByteArray();
Just use NIO. It's designed for this specific purpose. ByteBuffer and IntBuffer will do what you need quickly, efficiently, and elegantly. It'll handle big/little endian conversion, "direct" buffers for high performance IO, and you can even mix data types into the byte buffer.
Convert integers into bytes:
ByteBuffer bbuffer = ByteBuffer.allocate(4*theIntArray.length);
IntBuffer ibuffer = bbuffer.asIntBuffer(); //wrapper--doesn't allocate more memory
ibuffer.put(theIntArray); //add your int's here; can use
//array if you want
byte[] rawBytes = bbuffer.array(); //returns array backed by bbuffer--
//i.e. *doesn't* allocate more memory
Convert bytes into integers:
ByteBuffer bbuffer = ByteBuffer.wrap(rawBytes);
IntBuffer ibuffer = bbuffer.asIntBuffer();
while(ibuffer.hasRemaining())
System.out.println(ibuffer.get()); //also has bulk operators
I have found the following code that may help you, since Integer in Java is always 4 bytes long.
public static byte[] intToFourBytes(int i, boolean bigEndian) {
if (bigEndian) {
byte[] data = new byte[4];
data[3] = (byte) (i & 0xFF);
data[2] = (byte) ((i >> 8) & 0xFF);
data[1] = (byte) ((i >> 16) & 0xFF);
data[0] = (byte) ((i >> 24) & 0xFF);
return data;
} else {
byte[] data = new byte[4];
data[0] = (byte) (i & 0xFF);
data[1] = (byte) ((i >> 8) & 0xFF);
data[2] = (byte) ((i >> 16) & 0xFF);
data[3] = (byte) ((i >> 24) & 0xFF);
return data;
}
}
You can find more information about the bigEndian parameter here:
http://en.wikipedia.org/wiki/Endianness
create a 4-byte array and copy the int to the array in 4 steps, with bitwise ANDs and bitshifting, like Paulo said.
But remember that block algorithms such as AES and DES work with 8 or 16 byte blocks so you will need to pad the array to what the algorithm needs. Maybe leave the first 4 bytes of an 8-byte array as 0's, and the other 4 bytes contain the integer.
Just use:
Integer.toString(int).getBytes();
Make sure you use your original int and getBytes() will return a byte array. No need to do anything else complicated.
To convert back:
Integer.parseInt(encryptedString);
My Simple Solution is that Encrypt Integer to the String by shifting ASCII Value of the Integer by the secret key you Provide.
Here is the Solution:
public String encodeDiscussionId(int Id) {
String tempEn = Id + "";
String encryptNum ="";
for(int i=0;i<tempEn.length();i++) {
int a = (int)tempEn.charAt(i);
a+=148113;
encryptNum +=(char)a;
}
return encryptNum;
}
public Integer decodeDiscussionId(String encryptText) {
String decodeText = "";
for(int i=0;i<encryptText.length();i++) {
int a= (int)encryptText.charAt(i);
a -= 148113;
decodeText +=(char)a;
}
int decodeId = Integer.parseInt(decodeText);
return decodeId;
}
Steps to Encode:
Here, First you convert the Given Integer into String by: String temp = givenInt + ""
Scan each character of String, Read ASCII of that character and add it with secret key as 148113 in this case.
Convert shifted Integer into Character and concatenate to the String encryptNum and finally return it.
Steps to Decode:
Scan each character of String, Read ASCII of that character and subtract it with secret key as previous.
Convert that value to character and concatenate with decodeText.
As previous encode output is always String '???' and vary according to number of digits of input Id.