I have a long variable in java and am converting it to a binary string, like
long var = 24;
Long.toBinaryString(val);
Now this prints only 7 bits, but I need to display all the 64 bits, i.e. all the leading zeros also, how can I achieve this?
The reason is I need to iterate through each bit and perform an operation according to the status, is there a better way to do it?
If you want to iterate through the bits, you might be better off testing each bit without converting it to a string:
if ((val & (1L << bitPosition)) != 0)
// etc
But, if you truly want a binary string, this is the easiest way to left-pad it with zeros:
string padding = "0000000000000000000000000000000000000000000000000000000000000000";
string result = padding + Long.toBinaryString(val);
result = result.substring(result.length() - 64, result.length()); // take the right-most 64 digits
You can use binary operators to access the individual bits of an long. The following code prints the individual bits of "i" as "true" or "false".
long i = 1024;
for(int n = 63; n >= 0; n--)
System.out.println(n + ": " + ((i & (1L << n)) != 0));
Not sure, but I think it should go like this:
int i=0, thisbit;
mask = 1;
while (i++ < 64)
{
thisbit = var & mask;
// check thisbit here...
//
var = var >>> 1;
mask*=2;
}
I would add little modification on #Robert's answer. Instead of declaring padding variable here, use Long.numberOfLeadingZeros(long).
Actually internally it make use of shift operators only.
Yes, see http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html for information on bitwise operations.
Otherwise use the Formatter: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html
This will work;
String s = Long.toBinaryString(val);
while (s.length() < 64)
{
s = "0" + s;
}
If you want to do this with a StringBuffer, so;
StringBuffer s = new StringBuffer(Long.toBinaryString(val));
while (s.length() < 64)
{
s.insert(0, "0");
}
String str = s.toString();
Related
I have a key for a cipher in the form "XY XY+1 XY+2 XY+3 XY+4 XY+5 FF FF" where XY is an unknown byte, for example, XY could be 00000000 so XY+1 is 00000001.
Also, FF is a constant so always 11111111.
l have an addBinary() method which simply adds 1 to any binary string I give it, however, I'm finding it hard to generate all binary strings composing of "xxxx... 11111111 11111111".
I also found this printB() method on StackOverflow which generates the strings but just not sure how to hard code the FF's into it.
static void printB()
{
for(int i = 0; i < Math.pow(2,8); i++)
{
String format="%0"+8+"d";
System.out.printf(format,Integer.valueOf(Integer.toBinaryString(i)));
System.out.println();
}
}
Any help on how to generate this strings would be appreciated
If you want to have the binary number to be prefixed with 0-s you have to do a bit of work. Here I used a StringBuilder filled with 0s, replacing from the end the binary representation without 0 padding.
for (int i = 0; i <= 0xFF; i++) {
StringBuilder builder = new StringBuilder("00000000");
String binary = Integer.toBinaryString(i);
builder.replace(8 - binary.length(), 8, binary);
System.out.println(builder);
}
I recommend not working with strings of "1" and "0" except for formatting output. Internally you should store your "key" as a byte[8], so:
byte[] key = new byte[8];
for(int i=0; i<6; i++) {
key[i] = (byte) x + i;
}
key[6] = (byte) 0xff;
key[7] = (byte) 0xff;
As a first shot at converting this to a printable string, you just need:
String result = IntStream.range(0,8)
.map(i -> key[i])
.mapToObj(n -> intToBinaryString(n))
.collect(Collectors.joining(" "));
... and then you need an intToBinaryString() method. There are plenty of SO answers describing how to do this - for example: Print an integer in binary format in Java
In order to send a chunk of bits from a 4 words String, I'm doing getting the byte array from the String and calculating the bit string.
StringBuilder binaryStr = new StringBuilder();
byte[] bytesFromStr = str.getBytes("UTF-8");
for (int i = 0, l = bytesFromStr.length; i < l; i++) {
binaryStr.append(Integer.toBinaryString(bytesFromStr[i]));
}
String result = binaryStr.toString();
The problem appears when I want to do the reverse operation: converting a bit string to a Java String encoded using UTF-8.
Please, Is there someone that can explain me the best way to do that?
Thanks in advance!
TL;DR Don't use toBinaryString(). See solution at the end.
Your problem is that Integer.toBinaryString() doesn't return leading zeroes, e.g.
System.out.println(Integer.toBinaryString(1)); // prints: 1
System.out.println(Integer.toBinaryString(10)); // prints: 1010
System.out.println(Integer.toBinaryString(100)); // prints: 1100100
For your purpose, you want to always get 8 bits for each byte.
You also need to prevent negative values from causing errors, e.g.
System.out.println(Integer.toBinaryString((byte)129)); // prints: 11111111111111111111111110000001
Easiest way to accomplish that is like this:
Integer.toBinaryString((b & 0xFF) | 0x100).substring(1)
First, it coerces the byte b to int, then retains only lower 8 bits, and finally sets the 9th bit, e.g. 129 (decimal) becomes 1 1000 0001 (binary, spaces added for clarity). It then excludes that 9th bit, in effect ensuring that leading zeroes are in place.
It's better to have that as a helper method:
private static String toBinary(byte b) {
return Integer.toBinaryString((b & 0xFF) | 0x100).substring(1);
}
In which case your code becomes:
StringBuilder binaryStr = new StringBuilder();
for (byte b : str.getBytes("UTF-8"))
binaryStr.append(toBinary(b));
String result = binaryStr.toString();
E.g. if str = "Hello World", you get:
0100100001100101011011000110110001101111001000000101011101101111011100100110110001100100
You could of course just do it yourself, without resorting to toBinaryString():
StringBuilder binaryStr = new StringBuilder();
for (byte b : str.getBytes("UTF-8"))
for (int i = 7; i >= 0; i--)
binaryStr.append((b >> i) & 1);
String result = binaryStr.toString();
That will probably run faster too.
Thanks #Andreas for your code. I test using your function and "decoding" again to UTF-8 using this:
StringBuilder revealStr = new StringBuilder();
for (int i = 0; i < result.length(); i += 8) {
revealStr.append((char) Integer.parseUnsignedInt(result.substring(i, i + 8), 2));
}
Thanks for all folks to help me.
I have a question about converting String type binary number to bit and write in the txt file.
For example we have String like "0101011" and want to convert to bit type "0101011"
then write in to the file on the disk.
I would like to know is there anyway to covert to string to bit..
i was searching on the web they suggest to use bitarray but i am not sure
thanks
Try this:
int value = Integer.parseInt("0101011", 2); // parse base 2
Then the bit pattern in value will correspond to the binary interpretation of the string "0101011". You can then write value out to a file as a byte (assuming the string is no more than 8 binary digits).
EDIT You could also use Byte.parseByte("0101011", 2);. However, byte values in Java are always signed. If you tried to parse an 8-bit value with the 8th bit set (like "10010110", which is 150 decimal), you would get a NumberFormatException because values above +127 do not fit in a byte. If you don't need to handle bit patterns greater than "01111111", then Byte.parseByte works just as well as Integer.parseInt.
Recall, though, that to write a byte to a file, you use OutputStream.write(int), which takes an int (not byte) value—even though it only writes one byte. Might as well go with an int value to start with.
You can try the below code to avoid overflows of the numbers.
long avoidOverflows = Long.parseLong("11000000000000000000000000000000", 2);
int thisShouldBeANegativeNumber = (int) avoidOverflows;
System.out.println("Currect value : " + avoidOverflows + " -> " + "Int value : " + thisShouldBeANegativeNumber);
you can see the output
Currect value : 3221225472 -> Int value : -1073741824
//Converting String to Bytes
bytes[] cipherText= new String("0101011").getBytes()
//Converting bytes to Bits and Convert to String
StringBuilder sb = new StringBuilder(cipherText.length * Byte.SIZE);
for( int i = 0; i < Byte.SIZE * cipherText .length; i++ )
sb.append((cipherText [i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
//Byte code of input in Stirn form
System.out.println("Bytecode="+sb.toString()); // some binary data
//Convert Byte To characters
String bin = sb.toString();
StringBuilder b = new StringBuilder();
int len = bin.length();
int i = 0;
while (i + 8 <= len) {
char c = convert(bin.substring(i, i+8));
i+=8;
b.append(c);
}
//String format of Binary data
System.out.println(b.toString());
shifters...
I've to do something, that twist my mind.
I'm getting a hex value as String (for example: "AFFE") and have to decide, if bit 5 of Byte one is set.
public boolean isBitSet(String hexValue) {
//enter your code here
return "no idea".equals("no idea")
}
Any hints?
Regards,
Boskop
The simplest way is to convert String to int, and use bit arithmetic:
public boolean isBitSet(String hexValue, int bitNumber) {
int val = Integer.valueOf(hexValue, 16);
return (val & (1 << bitNumber)) != 0;
} ^ ^--- int value with only the target bit set to one
|--------- bit-wise "AND"
Assuming that byte one is represented by the last two digits, and the size of the string fixed to 4 characters, then the answer may be:
return (int)hexValue[2] & 1 == 1;
As you an see, you don't need to convert the whole string to binary to evaluate the 5th bit, it is indeed the LSB of the 3rd character.
Now, if the size of the hex string is variable, then you will need something like:
return (int)hexValue[hexValue.Length-2] & 1 == 1;
But as the string can have a length smaller than 2, it would be safer:
return hexValue.Length < 2 ? 0 : (int)hexValue[hexValue.Length-2] & 1 == 1;
The correct answer may vary depending on what you consider to be byte 1 and bit 5.
How about this?
int x = Integer.parseInt(hexValue);
String binaryValue = Integer.toBinaryString(x);
Then you can examine the String to check the particular bits you care about.
Use the BigInteger and it's testBit built-in function
static public boolean getBit(String hex, int bit) {
BigInteger bigInteger = new BigInteger(hex, 16);
return bigInteger.testBit(bit);
}
I get hex strings of 14 bytes, e.g. a55a0b05000000000022366420ec.
I use javax.xml.bind.DatatypeConverter.parseHexBinary(String s) to get an array of 14 bytes.
Unfortunately those are unsigend bytes like the last one 0xEC = 236 for example.
But I would like to compare them to bytes like this:
if(byteArray[13] == 0xec)
Since 235 is bigger than a signed byte this if statement would fail.
Any idea how to solve this in java?
Thx!
Try if(byteArray[13] == (byte)0xec)
You can promote the byte to integer:
if((byteArray[13] & 0xff) == 0xec)
since java doesn't support (atleast with primitives) any unsigned data types, you should look at using int as your data type to parse the string..
String str = "a55a0b05000000000022366420ec";
int[] arrayOfValues = new int[str.length() / 2];
int counter = 0;
for (int i = 0; i < str.length(); i += 2) {
String s = str.substring(i, i + 2);
arrayOfValues[counter] = Integer.parseInt(s, 16);
counter++;
}
work with the arrayOfValues...