Converting hexadecimal to little endian - java

What is the formula to convert the value of a textfield from hex to little endian?
Example input: 5A109061
Example output: 1636831322

Get the value from the EditText as a String.
Parse the string value as hex, using Integer.parseInt(...) and radix 16.
Flip the byte order of the int, either using ByteBuffer (simpler) or using bit shifts (faster).
For example:
String hex = "5A109061"; // mEditText.getText().toString()
// Parse hex to int
int value = Integer.parseInt(hex, 16);
// Flip byte order using ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.order(ByteOrder.BIG_ENDIAN);
buffer.asIntBuffer().put(value);
buffer.order(ByteOrder.LITTLE_ENDIAN);
int flipped = buffer.asIntBuffer().get();
System.out.println("hex: 0x" + hex);
System.out.println("flipped: " + flipped);
Output:
hex: 0x5A109061
flipped: 1636831322

Use ByteBuffer
ByteBuffer byteBuffer = ByteBuffer.allocate(8)order(ByteOrder.LITTLE_ENDIAN).putLong(5A109061)
byte[] result = byteBuffer.array();

You can also use this extension for kotlin.
Example :
val str = "6a3b7043"
val hex2Float = str.hex2Float
fun String.hex2Float(): Float{
val i = toLong(16)
val data = java.lang.Float.intBitsToFloat(i.toInt()) // Big endian
val buffer = ByteBuffer.allocate(4)
buffer.asFloatBuffer().put(data)
buffer.order(ByteOrder.LITTLE_ENDIAN)
val lData = buffer.asFloatBuffer().get() // Little endian
return lData
}

Related

Adding a zero byte to the start of a binary hash?

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);

Convert hex to INT 32 and STRING Little Endian

First question:
Hex: F1620000
After convert hex to INT 32 i expect 253229, but i get -245235712.
I've tried these methods:
Integer.parseUnsignedInt(value, 16));
(int)Long.parseLong(value, 16));
new BigInteger(value, 16).intValue());
How i can get correct value?
Second question:
Hex: 9785908D9B9885828020912E208D2E
After covert hex to STRING i can get this value:
\u0097\u0085\u0090\u008d\u009b\u0098\u0085\u0082\u0080 \u0091. \u008d.
How can I display this value correctly in json? (usning JSONObject).
StringBuilder result = new StringBuilder();
for (int i = 0; i < value.length(); i += 2) {
String str = value.substring(i, i + 2);
result.append((char)Integer.parseInt(str, 16));
}
All your attempts are sufficient for parsing a hexadecimal string in an unsigned interpretation, but did not account for the “little endian” representation. You have to reverse the bytecode manually:
String value = "F1620000";
int i = Integer.reverseBytes(Integer.parseUnsignedInt(value, 16));
System.out.println(i);
25329
For your second task, the missing information was how to interpret the bytes to get to the character content. After searching a bit, the Codepage 866 seems to be the most plausible encoding:
String value = "9785908D9B9885828020912E208D2E";
byte[] bytes = new BigInteger(value, 16).toByteArray();
String result = new String(bytes, bytes[0]==0? 1: 0, value.length()/2, "CP866");
ЧЕРНЫШЕВА С. Н.

Convert BigInteger to String using Base64 and reverse the result

I try to convert BigInteger to a string using Base64 and check the reversibility :
This case works fine :
Check A1 : "999999999" => "O5rJ/w=="
Check B1 : "O5rJ/w==" => "999999999"
but this case doesn't :
Check B2 : "//////" => "4294967295"
Check A2 : "4294967295" => "/////w" instead of "//////"
I'm using Java 8 and org.apache.commons.codec.binary.Base64
#Test
public void testDecimalToBase64()
{
final String encodedMaxDec = new String(Base64.encodeInteger(new BigInteger("999999999")), StandardCharsets.UTF_8);
Assert.assertEquals("Check A1", "O5rJ/w==", encodedMaxDec);
final String encodedMaxB64 = new String(Base64.encodeInteger(new BigInteger("4294967295")), StandardCharsets.UTF_8);
Assert.assertEquals("Check A2", "//////", encodedMaxB64);
}
#Test
public void testBase64ToDecimal()
{
final BigInteger decodedMaxDec = Base64.decodeInteger(new String("O5rJ/w==").getBytes(StandardCharsets.UTF_8));
Assert.assertEquals("Check B1", "999999999", decodedMaxDec.toString());
final BigInteger decodedMaxB64 = Base64.decodeInteger(new String("//////").getBytes(StandardCharsets.UTF_8));
Assert.assertEquals("Check B2", "4294967295", decodedMaxB64.toString());
}
If anyone has an idea, thank you for helping me ;-)
The base64 encoding of a BitInteger's bytes when representing 4294967295 isn't //////.
I'm assuming that because every integer in Java is signed the BigInteger sticks an additional byte on the front to indicate whether the number is positive or negative.
Therefore this code...
byte[] bigIntegerBytes = BigInteger.valueOf(4294967295l).toByteArray();
.. returns a 5 byte array and you have the following bytes:
000000000 11111111 11111111 11111111 1111111
If you base64 encode that you get AP////8=
If what you want to do is base64 encode a BigInteger representing 4294967295 and then decode it back again, this should do it.
Base64.Encoder encoder = Base64.getEncoder();
Base64.Decoder decoder = Base64.getDecoder();
byte[] bigIntegerBytes = BigInteger.valueOf(4294967295l).toByteArray();
String base64EncodedBigIntegerBytes = encoder.encodeToString(bigIntegerBytes);
System.out.println(base64EncodedBigIntegerBytes);
byte[] decodedBigIntegerBytes = decoder.decode(base64EncodedBigIntegerBytes);
BigInteger decodedBigInteger = new BigInteger(decodedBigIntegerBytes);
System.out.println(decodedBigInteger);

new String(byte[]), String.valueOf(byte[]), Arrays.toString(byte[]), and anyother toString method in java

In java, how can I convert a byte array to java with exactly same size of memory.
eg:
byte[] byteArr = new byte[16];
byteArr[0] = 0;
byteArr[1] = 1;
How can I convert byteArr to a String with 16 byte memory?
According to the comments of the java source code, new String(byte[]) "may not be equal to the length of the byte array"; String.valueOf(byte[]) and Arrays.toString(byte[]) seem to return ", ".
Is there any other method I can use?
byte[] bytes = new byte[16];
bytes[0] = 0;
bytes[1] = 1;
String test = new String(bytes);
System.out.println(test.getBytes().length);
new String(byte[]) can equal to the length of the byte array, they have the same number of bytes.

Using java to encrypt integers

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.

Categories

Resources