How to convert a String Mac Address to a Byte array - java

I have got the String MacAddress, which i need to convert in to a byte array. Java wouldn't let me do a direct conversion throwing a numberformat exception. This is what I'm doing right now
clientMac[0] = (byte)Integer.parseInt(strCameraMacId.substring(0, 2));
I tried doing it step by step
String mc = strCameraMacId.substring(0,2);
int test = Integer.parseInt(mc);
clientMac[0] = (byte) test;
But the String mc consists of a value "08" and after doing the int to byte converion im losing the zero.
the mac address im trying to convert is "08-00-23-91-06-48" and I might end up losing all the zeros. will I? and has anyone got an idea regarding how to approach this issue?
Thanks a lot

You are not losing the '0'. Because a byte is not a string, and 8 and 08 are the same.
But more important is this mistake in your code:
You're using the parseInt method. This parses your addresses as decimal integers. This won't work, because MAC addresses, when split the way you show them are usually HEX digits. You can come across 'A8' instead of '08' for example.
You need to use a different method:
Integer.parseInt(String s, int radix)
Pass the radix as 16 and you should be good.

The zero is going to be implied in the byte value. Remember that 0x08 == 8. You should be able to convert your to an array of 6 bytes. Youre approach is fine, just remember that if you are going to convert this back to a string, that you need to let Java know that you want to pad each number back to 2 chars. That will put your implied zeros back in place.

The IPAddress Java library will do this for you and will handle lots of different MAC address string formats, like aa:bb:cc:dd:ee:ff, aa-bb-cc-dd-ee-ff, aabb.ccdd.eeff, and so on. Disclosure: I am the project manager for that library.
Here is how to get a byte array:
String str = "aa:bb:cc:dd:ee:ff";
MACAddressString addrString = new MACAddressString(str);
try {
MACAddress addr = addrString.toAddress();
byte bytes[] = addr.getBytes();//get the byte array
//now convert to positive integers for printing
List<Integer> forPrinting = IntStream.range(0, bytes.length).map(index -> 0xff & bytes[index]).boxed().collect(Collectors.toList());
System.out.println("bytes for " + addr + " are " + forPrinting);
} catch(AddressStringException e) {
//e.getMessage provides validation issue
}
The output is:
bytes for aa:bb:cc:dd:ee:ff are [170, 187, 204, 221, 238, 255]

Related

Why am I getting a number format exception when the data type accepts the values im parsing?

I do not want the answer, I would just like guidance and for someone to point to why my code is not performing as expected
My task is to flip an integer into binary, reformat the binary to a 32 bit number and then return the unsigned integer. So far my code successfully makes the conversions and flips the bits however I am getting a NumberFormatException when I attempt to parse the string value into a long that ill convert to an unsigned integer.
What is the issue with my code? What have I got misconstrued here? I know there are loads of solutions to this problem online but I prefer working things out my own way?
Could I please get some guidance? Thank you
public class flippingBits {
public static void main(String[] args) {
//change the number to bits
long bits = Long.parseLong(Long.toBinaryString(9));
String tempBits = String.valueOf(bits);
//reformat so that you get 32 bits
tempBits = String.format("%" + (32) + "s", tempBits).replace(" ", "0");
//flip the bits
tempBits = tempBits.replace("1", "5");
tempBits = tempBits.replace("0", "1");
tempBits = tempBits.replace("5", "0");
//Pass this to a long data type so that you can then eventually convert the new bits
// to an unsigned integer
long backToNum = Long.parseLong(tempBits);
}
}
You're directly parsing the bits into a long value instead of converting the bits into an equivalent value.
You need to use the following method (Long.parseUnsignedLong()):
long backToNum = Long.parseUnsignedLong(tempBits, 2); //output: 4294967286
The second argument represents radix:
To interpret a number written in a particular representation, it is necessary to know the radix or base of that representation. This allows the number to be converted into a real value.
See the representation of each radix (From Wikipedia):

Compiler error "Incompatible types" on byte literal

I have seen many cases where a byte is declared but where the value from a method like
intToByte or StringToByte is casted to a byte because the programmer is provideing i.e. a hexadecimal- value, an Integer- or a String-value.
I am trying to assign an actual byte value to the variable without any casting or methods to parse, like so:
public class ByteTest {
/**
* This array will be used to hold three characters, together forming a string.
*/
private static byte[] string;
/**
* The main method of the program, where the byte-array is coming to use.
*/
public static void main(String args[]) {
//Construct the array with a limit to three bytes.
string = new byte[3];
/*
* Fill the three bytes with the binary values to create "O", "l" and "e".
*/
string[0] = 01001111;
string[1] = 01101100;
string[2] = 01100101;
//Print out "Ole".
System.out.println(string[0] + string[1] + string[2]);
}
}
But I get the following error in the compiler:
java\ByteTest.java:8: error: incompatible types: possible lossy conversion from int to byte
string[0] = 01001111;
^
java\ByteTest.java:9: error: incompatible types: possible lossy conversion from int to byte
string[1] = 01101100;
^
java\ByteTest.java:10: error: incompatible types: possible lossy conversion from int to byte
string[2] = 01100101;
^
Appearently, what I think of as eight bits, the compiler thinks of as eight integers.
Is there any other solution to this, where I can provide actually bits directly to the variables/array?
Indicate binary
string[0] = 0b01001111;
string[1] = 0b01101100;
string[2] = 0b01100101;
This reminds me of the joke: there are 10 kinds of programmers: those that understand binary and those that do not.
As bytes are signed there still is a problem with 0b1xxxxxxx which would need to be a negative number. In that case use the following trick:
string[2] = 0b11100101 - 256;
string[2] = (byte) 0b11100101; // Or simply cast the int range value.
Also binary is ideal for an underscore usage:
string[2] = 0b0110_0101; // 0x65
And is commented by #BackSlash: bytes are binary data. To interprete them as text they have to be associated with some Charset/encoding.
String s = new String(string, StandardCharsets.US_ASCII);
System.out.println(s);
This converts the bytes, interpreting them as ASCII to the Unicode that String uses (to combine all scripts of the world).
Adding 0 in front of constant number ( like 01101100 ) is interpreted as octal value
What do you need to do to fix this?
The simplest solution which will use the least memory (code and data) is also the simplest.
private static final String string = "Ole";
System.out.println(string);
otherwise you can do this
private static final char[] chars = {
(char) 0b01001111,
(char) 0b01101100,
(char) 0b01100101 };
String s = new String(chars);
System.out.println(s);
Note: characters in Java are 16-bit unsigned char, not 8 bit byte
To get an idea of why the class file is bigger you can dump the class file with
java -c -v -cp target/classes mypackage.MyClass
To start with 01001111 is in octal, not binary. To write a binary number, you need 0b01001111
Numbers don't "remember" how many leading zeros you gave it, and generally speaking, leading zeros are dropped when printed.
The default format for a number is decimal, not binary.
When you add two, or three numbers, you get another number. Assuming you got this to compile it would print something like
288
or whatever the sum of the values are.
BTW it is really confusing to name an int called "string" because this could be assumed to be a String
Assign Actual value :-
String a ="100101";
System.out.println(""+a);
Output :- 100101
Binary to integer conversion and then assign value to string variable :-
String a=""+0b100101
System.out.println(""+a);
Output: 37

android java - converting string to byte variable

I'm writing a little program in android and in it I've a list of byte values in a string variable. something like this :
String src = "255216173005050";
Now, what i need to do is to extract the byte values from the source string and store them in a byte variables. (in above source string, i'll have 5 bytes to store)
For doing this i could successfully read source string and separate the byte values by 3 characters. (255, 216, 173, 005, 050)
The problem is that i failed to convert these strings to their byte values.
it is what I've already done :
String str = "255";
byte b = (byte) Integer.parseInt(str);
By running this, b will be -60 !
Is there
Please help me !
When you write
byte b = (byte) Integer.parseInt(str);
you will get a signed byte. If you look at your int that is discarded using something like
int i = Integer.parseInt(str);
System.out.println(i);
byte b = (byte) i;
you will probably see that i contains the value you want.
This should work. Then just access various indices of the byte array to get the individual pieces. If your text is an abnormal character set - then pass the character set into the getBytes() method.
byte[] bytes = src.getBytes();
Don't use parseInt when you want a byte; instead try Byte.parseByte. Also note that bytes have a range of -128 to 127 (inclusive).

Java parsing long from string

I'm currently trying to parse some long values stored as Strings in java, the problem I have is this:
String test = "fffff8000261e000"
long number = Long.parseLong(test, 16);
This throws a NumberFormatException:
java.lang.NumberFormatException: For input string: "fffff8000261e000"
However, if I knock the first 'f' off the string, it parses it fine.
I'm guessing this is because the number is large and what I'd normally do is put an 'L' on the end of the long to fix that problem. I can't however work out the best way of doing that when parsing a long from a string.
Can anyone offer any advice?
Thanks
There's two different ways of answering your question, depending on exactly what sort of behavior you're really looking for.
Answer #1: As other people have pointed out, your string (interpreted as a positive hexadecimal integer) is too big for the Java long type. So if you really need (positive) integers that big, then you'll need to use a different type, perhaps java.math.BigInteger, which also has a constructor taking a String and a radix.
Answer #2: I wonder, though, if your string represents the "raw" bytes of the long. In your example it would represent a negative number. If that's the case, then Java's built-in long parser doesn't handle values where the high bit is set (i.e. where the first digit of a 16 digit string is greater than 7).
If you're in case #2, then here is one (pretty inefficient) way of handling it:
String test = "fffff8000261e000";
long number = new java.math.BigInteger(test, 16).longValue();
which produces the value -8796053053440. (If your string is more than 16 hex digits long, it would silently drop any higher bits.)
If efficiency is a concern, you could write your own bit-twiddling routine that takes the hex digits off the end of the string two at a time, perhaps building a byte array, then converting to long. Some similar code is here:
How to convert a Java Long to byte[] for Cassandra?
The primitive long variable can hold values in the range from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 inclusive.
The calculation shows that fffff8000261e000 hexademical is 18,446,735,277,656,498,176 decimal, which is obviously out of bounds. Instead, fffff8000261e000 hexademical is 1,152,912,708,553,793,536 decimal, which is as obviously within bounds.
As everybody here proposed, use BigInteger to account for such cases. For example, BigInteger bi = new BigInteger("fffff8000261e000", 16); will solve your problem. Also, new java.math.BigInteger("fffff8000261e000", 16).toString() will yield 18446735277656498176 exactly.
The number you are parsing is too large to fit in a java Long. Adding an L wouldn't help. If Long had been an unsigned data type, it would have fit.
One way to cope is to divide the string in two parts and then use bit shift when adding them together:
String s= "fffff8000261e000";
long number;
long n1, n2;
if (s.length() < 16) {
number = Long.parseLong(s, 16);
}
else {
String s1 = s.substring(0, 1);
String s2 = s.substring(1, s.length());
n1=Long.parseLong(s1, 16) << (4 * s2.length());
n2= Long.parseLong(s2, 16);
number = (Long.parseLong(s1, 16) << (4 * s2.length())) + Long.parseLong(s2, 16);
System.out.println( Long.toHexString(n1));
System.out.println( Long.toHexString(n2));
System.out.println( Long.toHexString(number));
}
Note:
If the number is bigger than Long.MAX_VALUE the resulting long will be a negative value, but the bit pattern will match the input.

Java - byte array from string [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Convert a string representation of a hex dump to a byte array using Java?
For example, I have a string "DEADBEEF". How can I convert it to byte[] bytes = { 0xDE, 0xAD, 0xBE, 0xEF } ?
Loop through each pair of two characters and convert each pair individually:
byte[] bytes = new byte[str.length()/2];
for( int i = 0; i < str.length(); i+=2 )
bytes[i/2] = ((byte)Character.digit(str.charAt(i),16))<<4)+(byte)Character.digit(str.charAt(i),16);
I haven't tested this code out (I don't have a compiler with me atm) but I hope I got the idea through. The subtraction/addition simply converts 'A' into the number 10, 'B' into 11, etc. The bitshifting <<4 moves the first hex digit to the correct place.
EDIT: After rethinking it a bit, I'm not sure if you're asking the correct question. Do you want to convert "DE" into {0xDE}, or perhaps into {0x44,0x45} ? The latter is more useful, the former is more like a homework problem type question.
getBytes() would get you the bytes of the characters in the platform encoding. However it sounds like you want to convert a String containing a Hex representation of bytes into the actual represented byte array.
In which case I would point you toward this existing question: Convert a string representation of a hex dump to a byte array using Java? (note: I personally prefer the 2nd answer to use commons-codec but more out of philosophical reasons)
You can parse the string to a long and then extract the bytes:
String s = "DEADBEEF";
long n = Long.decode( "0x" + s ); //note the use of auto(un)boxing here, for Java 1.4 or below, use Long.decode( "0x" + s ).longValue();
byte[] b = new byte[4];
b[0] = (byte)(n >> 24);
b[1] = (byte)(n >> 16);
b[2] = (byte)(n >> 8);
b[3] = (byte)n;
tskuzzy's answer might be right (didn't test) but if you can, I'd recommend using Commons Codec from Apache. It has a Hex class that does what you need.

Categories

Resources