I want to set the current time as the major and minor values of a beacon. Lets suppose this is the current time 1465398279009. I want 9827 to be the value of the major and 9009 the value of the minor. I use a java code to call the shell script. this is my java code
Long millis = System.currentTimeMillis();
String time=Long.toString(millis);
// String major1=time.substring(...);
String major1="99";
String major2="99";
String minor1="99";
String minor2="99";
ProcessBuilder pb2=new ProcessBuilder("/test.sh");
pb2.environment().put("major1", major1);
pb2.environment().put("major2", major2);
pb2.environment().put("minor1", minor1);
pb2.environment().put("minor2", minor2);
Process script_exec = pb2.start();
and this is the content of test.sh
sudo hcitool -i hci0 cmd 0x08 0x0008 1e 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d sd fh fb 33 j2 k9 j9 23 h2 n9 g7 v7 $param1 $major1 $major2 $minor1 $minor2 c5 00
In this example I just try to put both values to 9999 and 9999, but I get 39321 as result, I think the values are converted to big endian. I get confused and I don't understand well in which type and how shall I convert the String.
Long.toString can take two parameters. The first parameter is the number and the second parameter is the radix of the conversion.
Using a radix of 16 (Long.toString(millis, 16)) would result in a standard hexstring using [1-9a-f].
Try this:
String major1 = String.format("%02X", (millis >> 32) & 0xff);
String major2 = String.format("%02X", (millis >> 16) & 0xff);
String minor1 = String.format("%02X", (millis >> 8) & 0xff);
String minor2 = String.format("%02X", millis & 0xff);
The code above accesses each byte out of the timestamp and assigns it to the proper field, then formats it as a two character (one byte) hex number. A two character hex number is what you want for the script.
Related
To preface I am new to java (so take it ez on me lol) but here is what I am trying to do:
I have a GPS puck that I am reading via usb. The GPS puck uses some UI but I am trying to capture the data so I can use for my own application. I am reading in the packet from the serial buffer and trying to strip it down to just the payload and dissect the fields into a hashMap (not sure if this is the right application for it or not).
I want to add that the reason I care about efficiency in this case is because data will be getting processed through every fairly rapidly as the GPS puck is constantly getting Sat data (approx. every 200/300ms), so I am trying to avoid any bottlenecking if possible.
Here is the code that I have dished out, I know that in the code the buffer is not reading anything but in an effort to remove redundant code, just assume the data written in the comments is what we would be saying if we sys.out.
/*
Assume this is serial data received from GPS serial packet:
B5 62 01 02 1C AA AA AA AA 01 02 03 04 0A 0B 0C 0D B1 B2 B3 B4 C1 C2 C3 C4 D1 D2 D3 D4 E1 E2 E3 E4 01 02;
| | / | / |
| \ len \ / CRC
/ | \ /
/ | \ PAYLOAD /
Header | \ /
class & id \ /
*/
HashMap<String, String> payloadDict = new HashMap<String, String> (); // HashMap to write to
Bytes[] buffer; // serial buffer
String byteToHex = DataTypeConverter.parseHexBinary(buffer); // converts byte data to string in Hex
// Since the first few fields in the packet are static (header, class & id, and len),
// I strip the HEX string to only contain the payload
int payloadStartIndex = byteToHex.indexOf("C") + 1;
String payload = byteToHex.substring(payloadStartIndex, payloadStartIndex + 29);
/*
Assume this is the payload string after we parse:
AA AA AA AA 01 02 03 04 0A 0B 0C 0D B1 B2 B3 B4 C1 C2 C3 C4 D1 D2 D3 D4 E1 E2 E3 E4
**added seperation every 2 hex values for readability,
but assume it's just one giant string
*/
// write to HashMap
payloadDict = NAV_POSLLH(payload);
/*
so to visualize what I would imagine being saved to the HashMap:
iTOW: AA AA AA AA
lon: 01 02 03 04
lat: 0A 0B 0C 0D
height: B1 B2 B3 B4
hMSL: C1 C2 C3 C4
hAcc: D1 D2 D3 D4
vAcc: E1 E2 E3 E4
*/
public Map<String, String> NAV_POSLLH(String dataArr) {
// Temp HashMap
HashMap<String, String> dict = new HashMap<String, String> ();
/*
this is the payload format.
payloadStructure are the names of the all the fields I want to parse
and hexOffset are the beginning of each field.
*/
String[] payloadStructure = new String[6] {"iTOW", "lon", "lat", "height", "hMSL", "hAcc", "vAcc"};
int[] hexOffset = new int[6] {0, 7, 11, 15, 20, 24};
// loop through each field
for(int i = 0; i < byteOffset.length; i++) {
String parse = "";
// I am not sure if this is the best way to handle out of index errors
// in java, but this is what I thought would work
if(byteOffset[i] == 24) {
parse = dataArr.substring(hexOffset[i]);
map.put(payloadStructure[i], parse);
return dict;
}
// parse the substring from the beginning of each hex offset
// to the next index -1
parse = dataArr.substring(byteOffset[i], hexOffset[i+1] -1);
map.put(payloadStructure[i], parse);
// finally return HashMap
return dict;
}
}
I am not sure if the comments explain the packet structure well enough or if it is confusing (because the format is janky), so I attached a screenshot of the packet layout I made.
So what I am trying to ask from all of this:
Based on what I am trying to accomplish, is this an efficient or even a correct way of implementing it? I am not sure if there is anything I am just obviously missing.
I am unable to compile or test any code right now so I am just trying to visualize what the output would be haha. Thanks so much for anyone's input!
I would make a Packet class and fill it using ByteBuffer. That class has great methods for parsing, including bulk get methods for various primitive sizes. You might consider using a ByteBuffer for the payload member of that class
This question already has answers here:
How to convert byte array to hex format in Java
(4 answers)
Closed 2 years ago.
So i have a piece of code, which converted byte[] from a binary file into int[] which then went on to be converted to String.
Example: 02 09 1A would translate to "2926" using String.valueOf(byte);
But this is where the fun begins: the old Code already split up the array before it became String so it didn't matter. Now i have code which needs to somehow figure out if there is a 2 9 or 29... How can i get the String to
- stay in Hex instead of "switching" to decimal and
- keep the zeros in the string
so i can always grab the next two chars, figure out which info they display and go on?
Input: 05 06 1D 11 07 08 01 32 21 28 2F 20 2E 21 34 22 25 33 01 02 09 0A FF 0B 0C 2!(/ .!4"%3
ΓΏ
Current Output: 562917781503340473246335234375112910-11112
Expected Output: 05061D110708013221282F202E21342225330102090AFF0B0C
(Didn't put my old code in here since it's based on int which is crap)
If I understand correctly, you have a byte[] as input, and you want to output a string that is all those bytes, in hex form, joined together:
private static String byteArrayToString(byte[] byteArray) {
StringBuilder builder = new StringBuilder();
for (byte b : byteArray) {
int i = Byte.toUnsignedInt(b);
if (i < 16) {
builder.append("0");
}
builder.append(Integer.toHexString(i).toUpperCase());
}
return builder.toString();
}
Note the use of Byte.toUnsignedInt. This converts things like -1 the byte to the int 0xff. This is required because Java's bytes are signed.
Also note where I pad with 0. I only do this if the byte is a single digit in hex. i < 16 is the condition to check this.
Another way:
char[] hexVals = {'0', '1','2','3','4','5','6','7','8','9','A', 'B','C','D','E','F'};
byte[] bytes = {5, 6, (byte)0xAB, (byte)0xde}; // sample input
char[] output = new char[bytes.length*2];
// split each byte's hex digits into two chars
for(int i=0; i < bytes.length; i++) {
output[2*i] = hexVals[(bytes[i] >> 4) & 0xf]; // HO nibble
output[2*i+1] = hexVals[bytes[i] & 0xf]; // LO nibble
}
System.out.println(new String(output)); // 0506ABDE
I'm trying to convert a hex message to ascii
and I don't understand why I get this error
String final = (msg1 + " " + msg2 + " " + msg3);
byte[] s = DatatypeConverter.parseHexBinary(final);
String final = new String(s);
and this is the error I get :(the data is correct )
java.lang.IllegalArgumentException: hexBinary needs to be even-length: 4C 4B 4C 41 36 4C 31 45 32 48 41 37 32 32 31 36 31 FF
parseHexBinary is documented to take the input as defined by xsd:hexBinary.
This means the input string must contain only hexadecimal characters and always pairs. Your input stream contains space characters, that must be removed prior to parsing.
input = input.replaceAll(" +", "");
I need to get some data from X509 certificate.
If I open a certificate file in windows, its showing its serial number in this format.
ex. 39 65 70 eb d8 9f 28 20 4e c2 a0 6b 98 48 31 0d
The same data I am trying to obtain using java. After get it loaded, I use
x509.getSerialNumber();
and result is : 76292708057987193002565060032465481997
So what is the difference between both of these ? I want the result as upper one.
Windows shows the hexadecimal representation of the serial number, whereas Java returns a BigInteger result from X509Certificate.getSerialNumber().
To display the BigInteger as a hexadecimal value, just call toString(16).
BigInteger bi = new BigInteger("76292708057987193002565060032465481997");
System.out.println(bi.toString(16));
Will output:
396570ebd89f28204ec2a06b9848310d
The first one is hexadecimal value of the certificate.
The other one is decimal.
Now it depends on how you convert the initial certificate bytearray for printing it out.
Lets say this is your certificate:
byte[] cert = { (byte) 0xFD, (byte) 0xB1, (byte) 0xDD, ..., (byte) 0x00 };
BigInteger certVal = new BigInteger(cert);
System.out.println("And result is (hex): " + certVal.toString(16));
How to convert ASCII to hexadecimal values in java.
For example:
ASCII: 31 32 2E 30 31 33
Hex: 12.013
You did not convert ASCII to hexadecimal value. You had char values in hexadecimal, and you wanted to convert it to a String is how I'm interpreting your question.
String s = new String(new char[] {
0x31, 0x32, 0x2E, 0x30, 0x31, 0x33
});
System.out.println(s); // prints "12.013"
If perhaps you're given the string, and you want to print its char as hex, then this is how to do it:
for (char ch : "12.013".toCharArray()) {
System.out.print(Integer.toHexString(ch) + " ");
} // prints "31 32 2e 30 31 33 "
You can also use the %H format string:
for (char ch : "12.013".toCharArray()) {
System.out.format("%H ", ch);
} // prints "31 32 2E 30 31 33 "
It's not entirely clear what you are asking, since your "hex" string is actually in decimal. I believe you are trying to take an ASCII string representing a double and to get its value in the form of a double, in which case using Double.parseDouble should be sufficient for your needs. If you need to output a hex string of the double value, then you can use Double.toHexString. Note you need to catch NumberFormatException, whenever you invoke one of the primitive wrapper class's parse functions.
byte[] ascii = {(byte)0x31, (byte)0x32, (byte)0x2E, (byte)0x30, (byte)0x31, (byte)0x33};
String decimalstr = new String(ascii,"US-ASCII");
double val = Double.parseDouble(decimalstr);
String hexstr = Double.toHexString(val);