Java create a checksum in ASCII - java

I have to sum the ASCII in a string and put the last character of the sum in a byte to send with the string on Bluetooth.
es: String s = "R002"
sum: R+0+0+2 = 000000000000000000000000000000000000c3a4 = ä
I try to send R(52)+0(30)+0(30)+2(32)+¤(a4)
but I send R(52)+0(30)+0(30)+2(32)+Ä(c3)+¤(a4) ,
In which way can i send ¤ without Ä?
the code:
String pergolato = "ä";
String pesto= String.format("%040x", new BigInteger(1, pergolato.substring(0, 1).getBytes(/*YOUR_CHARSET?*/)));
int zaino = Integer.parseInt(pesto, 16);
char c = (char) (zaino & 0xff);
String sum="R002"+c;
for(int i=0;i<sum.length();i++){
String s= String.format("%040x", new BigInteger(1, sum.substring(i, i+1).getBytes(/*YOUR_CHARSET?*/)));
Log.i(TAG, sum.charAt(i)+" "+s);
}
the LogCat:
R 0000000000000000000000000000000000000052
0 0000000000000000000000000000000000000030
0 0000000000000000000000000000000000000030
2 0000000000000000000000000000000000000032
¤ 000000000000000000000000000000000000c2a4

I modified the code a bit for my purpose.
Results with different encoding :
UTF-8 --> ¤ 000000000000000000000000000000000000c2a4
UTF-16 --> ¤ 00000000000000000000000000000000feff00a4
UTF-32 --> ¤ 00000000000000000000000000000000000000a4
import java.math.BigInteger;
import java.nio.charset.Charset;
public class Test2 {
public static void main(String[] args) {
String pergolato = "ä";
String pesto= String.format("%040x", new BigInteger(1, pergolato.getBytes()));
int zaino = Integer.parseInt(pesto, 16);
char c = (char) (zaino & 0xff);
String sum="R002"+c;
for(int i=0;i<sum.length();i++){
String s= String.format("%040x", new BigInteger(1, sum.substring(i, i+1).getBytes(Charset.forName("UTF-32"))));
System.out.println(sum.charAt(i)+" "+s);
}
}
}

resolved:
somma=(char) (somma%128);

Related

How to convert hexstring to ANSI (window 1252) and convert ANSI (window 1252) back to hex string in Java?

How to convert hex string to ansi (window 1252) and ansi (window 1252)to hex string in Java.
python (Works perfectly)
q = "hex string value"
x = bytes.fromhex(q).decode('ANSI')
a = x.encode("ANSI")
a = a.hex()
if q==a:
print("Correct")
Java (This code has a problem)
String hexOri = "hex string value";
StringBuilder output = new StringBuilder();
for (int i = 0; i < hexOri.length(); i+=2) {
String str = hexOri.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
System.out.println("ANSI = " + output);
char [] chars = output.toString().toCharArray();
StringBuffer hexOutput = new StringBuffer();
for(int i = 0; i < chars.length; i++){
hexOutput.append(Integer.toHexString((int)chars[i]));
}
System.out.println("HexOutput = " + hexOutput.toString());
System.out.println(hexOri.equals(hexOutput.toString()));
Output from Python
Correct
Expected Output from Python
Correct
Output from Java
False
Expected Output from Java
Correct
In java the strings are encoded in UTF-16, so you can't read simply read/write the bytes of a string to get the encoding representation you desire.
You should use String#getBytes(String str, String charset) to get the string converted in the encoding you need and serialized to a byte array.
The same thing must be done to decode a byte array, using new String(buffer,encoding).
In both cases if you use the method without the charset it will use the default encoding for the JVM instance (which should be the system charset).
public static void main(String[] args) {
String str = "\tSome text [à]";
try {
System.out.println(str); // Some text [à]
String windowsLatin1 = "Cp1252";
String hexString = toHex(windowsLatin1, str);
System.out.println(hexString); // 09536f6d652074657874205be05d
String winString = toString(windowsLatin1, hexString);
System.out.println(winString); // Some text [à]
} catch (UnsupportedEncodingException e) {
// Should not happen.
}
}
public static String toString(String encoding, String hexString) throws UnsupportedEncodingException {
int length = hexString.length();
byte [] buffer = new byte[length/2];
for (int i = 0; i < length ; i+=2) {
String hexVal = hexString.substring(i,i+2);
byte code = (byte) Integer.parseInt(hexVal,16);
buffer[i/2]=code;
}
String winString = new String(buffer,encoding);
return winString;
}
public static String toHex(String encoding, String str) throws UnsupportedEncodingException {
byte[] bytes = str.getBytes(encoding);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
String hexChar = Integer.toHexString(b & 0xff);
if(hexChar.length()<2) {
builder.append('0');
}
builder.append(hexChar);
}
String hexString = builder.toString(); // 09536f6d652074657874205be05d
return hexString;
}

php pack('H*',$securesecret) equivalant in Java

In PHP Without pack function
$message = "hello world";
$key = "7E066";
echo hash_hmac('SHA256',$message, $key);
I get 0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e
In Java
String data = "hello world";
String key = "7E066";
System.out.println(hmacSha(key,data, "HmacSHA256"));
private static String hmacSha(String KEY, String VALUE, String SHA_TYPE) {
try {
SecretKeySpec signingKey = new SecretKeySpec(KEY.getBytes("UTF-8"), SHA_TYPE);
Mac mac = Mac.getInstance(SHA_TYPE);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(VALUE.getBytes("UTF-8"));
byte[] hexArray = {
(byte)'0', (byte)'1', (byte)'2', (byte)'3',
(byte)'4', (byte)'5', (byte)'6', (byte)'7',
(byte)'8', (byte)'9', (byte)'a', (byte)'b',
(byte)'c', (byte)'d', (byte)'e', (byte)'f'
};
byte[] hexChars = new byte[rawHmac.length * 2];
for ( int j = 0; j < rawHmac.length; j++ ) {
int v = rawHmac[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
I get 0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e too.
In PHP with Pack function
$message = "hello world";
$key = "7E066";
echo hash_hmac('SHA256',$message, pack('H*',$key));
I get 33e97719c1b98f64bd0394e7fe94f43eae927e15f9eda15aeff0830bc3dd2fc3
I don't understand what pack function does, I can not write same function in Java. Could anyone help me please?
Try this:
public String pack(String hex) {
String input = hex.length() % 2 == 0 ? hex : hex + "0";
StringBuilder output = new StringBuilder();
for (int i = 0; i < input.length(); i+=2) {
String str = input.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
return output.toString();
}
for this data it returns exactly that you need:
String data = "hello world";
String key = "7E066";
System.out.println(hmacSha(key,data, "HmacSHA256"));
System.out.println(hmacSha(pack(key), data, "HmacSHA256"));
0315a69471ebe855e9e221a374b30d8de08dcc833857f964737632698c87278e
33e97719c1b98f64bd0394e7fe94f43eae927e15f9eda15aeff0830bc3dd2fc3
The trick is that the pack() PHP function for input hexadecimal string of the odd length shift it to the left, i.e. add one zero to the right of the value. This is because it is only possible to calculate binary string for even-length input hexadecimal string.
In my case work only this:
import org.apache.geronimo.mail.util.Hex;
public class TestEncoding {
public static void main(String[] args) {
System.out.println(Hex.decode(("48398018")));
}
}
Result:
H9�
It was equivalent PHP code:
$nonce = 48398018;
pack('H*', $nonce);
echo $nonce;
Result: H9�

Convert Hexadecimal to String

To convert String to Hexadecimal i am using:
public String toHex(String arg) {
return String.format("%040x", new BigInteger(1, arg.getBytes("UTF-8")));
}
This is outlined in the top-voted answer here:
Converting A String To Hexadecimal In Java
How do i do the reverse i.e Hexadecimal to String?
You can reconstruct bytes[] from the converted string,
here's one way to do it:
public String fromHex(String hex) throws UnsupportedEncodingException {
hex = hex.replaceAll("^(00)+", "");
byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < hex.length(); i += 2) {
bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16));
}
return new String(bytes);
}
Another way is using DatatypeConverter, from javax.xml.bind package:
public String fromHex(String hex) throws UnsupportedEncodingException {
hex = hex.replaceAll("^(00)+", "");
byte[] bytes = DatatypeConverter.parseHexBinary(hex);
return new String(bytes, "UTF-8");
}
Unit tests to verify:
#Test
public void test() throws UnsupportedEncodingException {
String[] samples = {
"hello",
"all your base now belongs to us, welcome our machine overlords"
};
for (String sample : samples) {
assertEquals(sample, fromHex(toHex(sample)));
}
}
Note: the stripping of leading 00 in fromHex is only necessary because of the "%040x" padding in your toHex method.
If you don't mind replacing that with a simple %x,
then you could drop this line in fromHex:
hex = hex.replaceAll("^(00)+", "");
String hexString = toHex("abc");
System.out.println(hexString);
byte[] bytes = DatatypeConverter.parseHexBinary(hexString);
System.out.println(new String(bytes, "UTF-8"));
output:
0000000000000000000000000000000000616263
abc

How to decode hex code in an array in java

Need to decode hex code in array when accessed by index.User should enter array index and get decoded hex in array as output.
import java.util.Scanner;
class Find {
static String[] data={ " \\x6C\\x65\\x6E\\x67\\x74\\x68",
"\\x73\\x68\\x69\\x66\\x74"
//....etc upto 850 index
};
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter a number");
int s = in.nextInt();
String decodeinput=data[s];
// need to add some code here
//to decode hex and store to a string decodeoutput to print it
String decodeoutput=......
System.out.println();
}
}
How about using...
String hexString ="some hex string";
byte[] bytes = Hex.decodeHex(hexString .toCharArray());
System.out.println(new String(bytes, "UTF-8"));
Append the following code after getting the value of s from user. Imp: Please use camelCase convention for naming variables as pointed out above. I have just gone ahead and used the same names as you have for your convinience for now.
if (s>= 0 && s < data.length) {
String decodeinput = data[s].trim();
StringBuilder decodeoutput = new StringBuilder();
for (int i = 2; i < decodeinput.length() - 1; i += 4) {
// Extract the hex values in pairs
String temp = decodeinput.substring(i, (i + 2));
// convert hex to decimal equivalent and then convert it to character
decodeoutput.append((char) Integer.parseInt(temp, 16));
}
System.out.println("ASCII equivalent : " + decodeoutput.toString());
}
OR, just complete what you were doing:
/* import java.io.UnsupportedEncodingException;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex; //present in commons-codec-1.7.jar
*/
if (s>= 0 && s < data.length) {
String hexString =data[s].trim();
hexString = hexString.replace("\\x", "");
byte[] bytes;
try {
bytes = Hex.decodeHex(hexString.toCharArray());
System.out.println("ASCII equivalent : " + new String(bytes, "UTF-8"));
} catch (DecoderException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}

Convert Base64 to Binary String in Java

I have the following 3 byte encoded Base64 string.
String base64_str = "MDQw";
System.out.println("base64:" + base64_str);
String hex = DatatypeConverter.printHexBinary(DatatypeConverter.parseBase64Binary(base64_str));
for (int i = 0; i < hex.length(); i+=6) {
String bytes = hex.substring(i, i+6);
System.out.println("hex: " + bytes);
StringBuilder binary = new StringBuilder();
int byte3_int = Integer.parseInt(bytes.substring(4, 6), 16);
String byte3_str = Integer.toBinaryString(byte3_int);
byte3_int = Integer.valueOf(byte3_str);
binary.append(String.format("%08d", byte3_int));
int byte2_int = Integer.parseInt(bytes.substring(2, 4), 16);
String byte2_str = Integer.toBinaryString(byte2_int);
byte2_int = Integer.valueOf(byte2_str);
binary.append(String.format("%08d", byte2_int));
int byte1_int = Integer.parseInt(bytes.substring(0, 2), 16);
String byte1_str = Integer.toBinaryString(byte1_int);
byte1_int = Integer.valueOf(byte1_str);
binary.append(String.format("%08d", byte1_int));
System.out.println("binary: " + binary);
}
}
My Output is:
base64:MDQw
hex: 303430
binary: 001100000011010000110000
The above output is correct, but is there a more efficient way on converting a base64 string to binary string?
Thanks in advance.
You can use BigInteger (import java.math.BigInteger;) to convert a base64 string to binary string.
byte[] decode = Base64.getDecoder().decode(base64_str);
String binaryStr = new BigInteger(1, decode).toString(2);
Here is a small code to perform your operation. The only flaw is the use of replace for padding the 0.
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
public class main {
public static void main(String [] args) throws UnsupportedEncodingException {
String base64_str = "MDQw";
byte[] decode = DatatypeConverter.parseBase64Binary(base64_str);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < decode.length; i++){
String temp = Integer.toBinaryString(decode[i]);
sb.append(String.format("%8s", temp).replace(" ", "0"));
}
System.out.println(sb.toString());
}
}

Categories

Resources