I'm not sure what is causing this exception, and the stack trace isn't being helpful as it states it was caused by an unknown source.
The method below takes two hexadecimal strings, one representing an opcode and one representing an operand, and converts them to binary before concatenating them and adding them to an arraylist. Simple enough. In order to ensure each binary string includes the full 8 bits I'm using a small utility method called hexToBinary, for some reason, when I attempt to use this method to convert my hexadecimal strings it causes the exception.
The opcode and operands, which are taken from the asmLine objects give this input below:
A9 10
90 C6
0A 00
11 FF
38 00
7D FF
81 FF
A1 09
AA 00
20 11
58 00
6C 09
FE 10
All of the above hexadecimal values should be converted to binary. But this is not happening. The strange thing is that when I explicitly state the hexadecimal value to be converted by the utility method, as I do with the line String beginBinary = Utils.hexToBinary("FA"); works completely normally. I just can't understand why this isn't working when I'm using the values pulled from the asmLine objects.
public void constructBinaryOutput()
{
ArrayList<String> binaryOut = new ArrayList<String>();
String beginBinary = Utils.hexToBinary("FA"); //This works normally
String endBinary = Utils.hexToBinary("FF"); //This works normally
String twoByteString = beginBinary.concat(" " + beginBinary);
binaryOut.add(twoByteString);
for(AssemblyLine asmLine : lineObjects)
{
String opcodeHex = asmLine.getOpcodeHEX();
String operandHex = asmLine.getOperandHEX();
System.out.println("Hex opcode/operand: " + opcodeHex + " " + operandHex);
String opcodeBinary = Utils.hexToBinary(opcodeHex); //This causes an exception
String operandBinary = Utils.hexToBinary(operandHex);
System.out.println("Hex opcode " + asmLine.getOpcodeHEX() + " converted into binary " + opcodeBinary);
System.out.println("Hex operand " + asmLine.getOperandHEX() + " converted into binary " + operandBinary);
twoByteString = opcodeBinary.concat(" " + operandBinary);
System.out.println("2 Byte instruction: " + twoByteString);
binaryOut.add(twoByteString);
}
}
Utility method hexToBinary
public static String hexToBinary(String hex)
{
String bin = Integer.toBinaryString(Integer.parseInt(hex,16));
int length = bin.length();
return length == 8 ? bin : "00000000".substring(length - 8) + bin;
}
Just a simple mistake in your util function. It should be:
public static String hexToBinary(String hex) {
String bin = Integer.toBinaryString(Integer.parseInt(hex, 16));
int length = bin.length();
return length == 8 ? bin : "00000000".substring(length) + bin;
}
notice the substring.
HTH,
Gal
Related
This question already has answers here:
how to encode and decode emoji in android?
(8 answers)
Closed 2 years ago.
I am making an ASCII Encoder-Decoder. I am encoding the characters into UTF-8. To encode I am using this code:
private String asciiReturn(String inpString){
int codePoint = 0;
StringBuilder str = new StringBuilder();
for (int i = 0; i < inpString.length(); i++){
codePoint = Character.codePointAt(inpString, i);
i += Character.charCount(codePoint) - 1;
str.append(codePoint);
str.append(" ");
}
return str.toString();
}
So by this, I can encode all those emoji characters too.
Like '🤷🏻♂️' for this emoji I am getting "129335 127995 8205 9794 65039". So this is basically the UTF-8 decimal value of the emoji and that's exactly what I want. But my problem is the decoding.
What I want is: (Example)
Input String: "72 117 104 33 129335 127995 8205 9794 65039"
Output String: "Huh!🤷🏻♂️"
Cause:
72 -> 'H'
117 -> 'u'
104 -> 'h'
33 -> '!'
129335 127995 8205 9794 65039 -> '🤷🏻♂️'
Thanks in advance 🙂
Try this.
private String decode(String inpString) {
return Arrays.stream(inpString.split("\\s+"))
.map(s -> Character.toString(Integer.parseInt(s)))
.collect(Collectors.joining());
}
and
String input = "72 117 104 33 129335 127995 8205 9794 65039";
System.out.println(decode(input));
output
Huh!🤷🏻♂️
You can also write your encoding method like this:
static String asciiReturn(String s) {
return s.codePoints()
.mapToObj(Integer::toString)
.collect(Collectors.joining(" "));
}
and
String s = "Huh!🤷🏻♂️";
System.out.println(asciiReturn(s));
output
72 117 104 33 129335 127995 8205 9794 65039
I want to take the byte value out of this class so I can parse it, or if it's possible parse it inside and get the 5th and 6th byte value out.
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
// This is special handling for the Heart Rate Measurement profile. Data parsing is
// carried out as per profile specifications:
// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
} else {
// For all other profiles, writes the data formatted in HEX.
}
}
sendBroadcast(intent);
}
How this works is that I step on a scale and it sends me these bytes:
00 00 00 00 02 02 00 00 00 00 00 00 00 00 00 00
Which is stored at the variable 'data'. How do I take 'data' out to use in another class?
The weight data is on bytes 5 and 6. If you convert the hex values of bytes 5 and 6, in that example is '0202' it becomes 514 in decimal (51.4kg).
I need to take the bytes data to use in another class to get the kg data. How would I go around doing so?
You can simply get those two bytes and apply below:
int result = ByteBuffer.wrap(bytes).getInt();
If you want more info: HERE1, HERE 2
I have a Java program that reads each value from a database and converts it to a byte array. I am currently trying to write an equivalent program in C#. However, I'm having difficulties with DateTimes. The Java code and the C# code produce different byte values.
Here is the Java code:
ResultSet rs = stmt.executeQuery("select * from " + query);
while (rs.next())
{
for (int j = 1; j <= rs.getMetaData().getColumnCount(); j++)
{
byte[] b = rs.getBytes(j);
if (!rs.wasNull() && b != null)
{
for(int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
}
Output for the DateTime 2/19/2016 3:12:21 PM:
-71 -3 65 70 116 -74 -28 64
Here is the C# code:
OleDbCommand cmd = new OleDbCommand("select * from " + name, conn);
OleDbDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
for (int i = 0; i < rdr.FieldCount; i++)
{
if (rdr[i] != DBNull.Value && rdr[i] is DateTime)
{
DateTime date = (DateTime)rdr[i];
byte[] b = BitConverter.GetBytes((long)date.Ticks);
foreach (byte bt in b)
Console.Write(unchecked((sbyte) bt) + " ");
}
}
}
Output for the DateTime 2/19/2016 3:12:21 PM:
-128 -72 98 16 63 57 -45 8
I am not sure how to get these to match. According to the Java documentation for ResultSet's getBytes(int columnIndex) method, "the bytes represent the raw values returned from the driver". So it seems that, unlike the standard C# protocol, it is NOT using the ticks value in order to produce the bytes. This becomes apparent when attempting to translate the byte array back into a DateTime. Converting -71 -3 65 70 116 -74 -28 64 into a long gives you 4676062923628608953. But that value exceeds the maximum tick value for a DateTime, so it cannot be converted into a valid DateTime.
So how does Java end up with those particular byte values then?
I need a way of converting DateTime to byte[ ] in C# that will ALWAYS have the same behavior as Java's getBytes(int columnIndex) method. I cannot modify the Java code. The C# output must match the Java output. Is this possible?
getBytes() is not defined for non-binary data, e.g. it may return driver-specific data.
The bytes represent the raw values returned by the driver.
It would seem that the particular database / JDBC driver you are using is sending the value as a double.
-71 -3 65 70 116 -74 -28 64 is actually b9 fd 41 46 74 b6 e4 40 in hex, which is the double value 42419.633576388886 in Little-Endian order.
byte[] b = { -71, -3, 65, 70, 116, -74, -28, 64 };
System.out.println(ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getDouble());
42419.633576388886
If you paste that into Excel and format it as m/d/yyyy h:mm:ss AM/PM, you get 2/19/2016 3:12:21 PM.
See here for how to convert in C#.
my hexadecimal string
string s=new String("FF7900002481201132570943440402151302961500080054021E000040FFFFFBFF79000024812011");
i want particular data in string..
my format : 2481201132570943440402151302961500080054021E000040FFFFFBFF790000
it's must starting value in string 24 .
and it's split at end of 62 . values(2481201132570943440402151302961500080054021E000040FFFFFBFF790000=62)
and finally to split the string ?
12 content value in hexadecimal
24 ---> (1)
8120113257 --(5)
094047 ---(3)
040215 ---(3)
13029615 ----- (4)
00 ------- (1)
080054021E -------(5)
000040 ---- (3)
FFFFFBFF -- (4)
79 ---(1)
00 ------(1)
00 ----- (1)
how to solve it in java code?
Thanks
You can parse the String as a series of Strings.
class StringParser {
final StringReader sr;
public StringParser(String text) {
sr = new StringReader(text);
}
public String next(int n) {
char[] chars = new char[n];
sr.read(chars);
return new String(chars);
}
public String nextAsLong(int n) {
return Long.parseInt(next(n));
}
}
StringParser sp = new StringParser("FF7900002481201132570943440402151302961500080054021E000040FFFFFBFF79000024812011");
sp.next(8); // ignored
long first= sp.nextAsLong(2);
long second = sp.nextLong(10);
// etc
You can use
Long.parseLong(string, 16);
Size of content is fixed or floating?
If yes you can use substring and: Long.parseLong("FFFFFBFF", 16);
So I have a string which is from a text file, essentially the text file is just 5 lines which read:
x=1
y=15
z=128
topx=100
leftx=150
label= this is a test
I am able to get the split to work once which separates via the '=' sign, but when I try to split the string again by \n nothing works, I have tried using "\r?\n", line.Separator etc. but the string value always stays the same, basically the 5 lines without the characters before the = sign. How would I pull out the individual lines to assign variables to?
Here is the code I have, basically the println is to try and see if I can get the first value '1' to list separate from the rest of the lines.
public static void main(String[] a) {
15 draw d = new draw();
16 Read r = new Read();
17 String m = r.doRead("variables.txt");
18
19 String[] ss = new String[5];
20 ss = m.split("\n");
21
22 String[] kv= new String[5];
23 for (int i=0; i<ss.length; i++) {
24 kv = ss[i].split("=");
25 String eol = System.getProperty("line.seperator");
26 String test = kv[1];
27 String[] split = new String[5];
28 split = test.split("\n");
29
30
31
32
33 String first = split[0];
34 //String second = split[1];
35 //String third = split[2];
36 //String fourth = split[3];
37 //String fifth = split[4];
38 System.out.println(first);
39 }
When every line looks like
x=1 y=15 z=128 topx=100 leftx=150 label= this is a test
you should first split at a whitespace to get 5 parts (x=1, y=15, ...) and then at = to get the "key" and "value" part of each part.
check this out:
String s = "x=1\ny=15\nz=128\ntopx=100\nleftx=150\nlabel= this is a test";
String[] ss = s.split("\n");
System.err.println( Arrays.asList(ss[0].split("=")) );