Convert each character of a string in bits - java

String message= "10";
byte[] bytes = message.getBytes();
for (int n = 0; n < bytes.length; n++) {
byte b = bytes[n];
for (int i = 0; i < 8; i++) {//do something for each bit in my byte
boolean bit = ((b >> (7 - i) & 1) == 1);
}
}
My problem here is that it takes 1 and 0 as their ASCII values, 49 and 48, instead of 1 and 0 as binary(00000001 and 00000000). How can I make my program treat each character from my string as a binary sequence of 8 bits?
Basicly, I want to treat each bit of my number as a byte. I do that like this byte b = bytes[n]; but the program treats it as the ASCII value.
I could assign the number to an int, but then, I can't assign the bits to a byte.

It's a bit messy, but the first thing that comes to mind is to first, split your message up into char values, using the toCharArray() method. Next, use the Character.getNumericValue() method to return the int, and finally Integer.toBinaryString.
Example
String message = "123456";
for(char c : message.toCharArray())
{
int numVal = Character.getNumericValue(c);
String binaryString = Integer.toBinaryString(numVal);
for(char bit : binaryString)
{
// Do something with your bits.
}
}

String msg = "1234";
for(int i=0 ; i<msg.length() ; i++ ){
String bits = Integer.toBinaryString(Integer.parseInt(msg.substring(i, i+1)));
for(int j=0;j<8-bits.length();j++)
bits = "0"+bits;
}
Now bits is a string of length 8.
1
00000001
10
00000010
11
00000011
100
00000100
You can use getBytes() on the String

Use Java's parseInt(String s, int radix):
String message= "10";
int myInt = Integer.parseInt(message, 2); //because we are parsing it as base 2
At that point you have the correct sequence of bits, and you can do your bit-shifting.
boolean[] bits = new boolean[message.length()];
System.out.println("Parsed bits: ");
for (int i = message.length()-1; i >=0 ; i--) {
bits[i] = (myInt & (1 << i)) != 0;
System.out.print(bits[i] ? "1":"0");
}
System.out.println();
You could make it bytes if you really want to, but booleans are a better representation of bits...

Related

Converting int/long to 64-bit binary

I'm looking for a better way to convert an int to 64 bit binary represented as String. Right now I'm converting int to 32bit binary and then adding 32 zeroes in front of it. I'm implementing SHA-1 and I need that int to be 64bit binary.
private static String convertIntTo64BitBinary(int input) {
StringBuilder convertedInt = new StringBuilder();
for(int i = 31; i >= 0; i--) { // because int is 4 bytes thus 32 bits
int mask = 1 << i;
convertedInt.append((input & mask) != 0 ? "1" : "0");
}
for(int i = 0; i < 32; i++){
convertedInt.insert(0, "0");
}
return convertedInt.toString();
}
EDIT 1:
Unfortunately this doesn't work:
int messageLength = message.length();
String messageLengthInBinary = Long.toBinaryString((long) messageLength);
messageLengthInBinary is "110"
EDIT 2:
To clarify:
I need the string to be 64 chars long so need all the leading zeros.
You could use the long datatype which is a 64 bit signed integer. Then calling Long.toBinaryString(i) would give you the binary representation of i
If you already have an int then you could cast it to a long and use the above.
This doesn't include the leading 0s so the resulting string needs padding to the 64 characters.
Something like this would work.
String value = Long.toBinaryString(i)
String zeros = "0000000000000000000000000000000000000000000000000000000000000000" //String of 64 zeros
zeros.substring(value.length()) + value;
See How can I pad a String in Java? for more options.

Java. Extracting integers from bits in a byte array not fitting the byte boundary

I have the following array of bytes:
01010110 01110100 00100101 01001011
These bytes are broken into two groups to encode seven integers. I know that the first group consists of 3 values 4 bits each (0101 0110 0111) that represent numbers 5,6,7. The second group consists of 4 values 5 bits each (01000 01001 01010 01011), which represent integers 8,9,10, and 11.
To extract the integers, I am currently using the following approach. Convert the array into a binary string:
public static String byteArrayToBinaryString(byte[] byteArray)
{
String[] arrayOfStrings = new String[byteArray.length];
for(int i=0; i<byteArray.length; i++)
{
arrayOfStrings[i] = byteToBinaryString(byteArray[i]);
}
String bitsetString = "";
for(String testArrayStringElement : arrayOfStrings)
{
bitsetString += testArrayStringElement;
}
return bitsetString;
}
// Taken from here: http://helpdesk.objects.com.au/java/converting-large-byte-array-to-binary-string
public static String byteToBinaryString(byte byteIn)
{
StringBuilder sb = new StringBuilder("00000000");
for (int bit = 0; bit < 8; bit++)
{
if (((byteIn >> bit) & 1) > 0)
{
sb.setCharAt(7 - bit, '1');
}
}
return sb.toString();
}
Then, I split the binary string into 2 substrings: 12 characters and 20 characters. Then I split each substring into new substrings, each of which has length that equals the number of bits. Then I convert each sub-substring into an integer.
It works but a byte array representing thousands of integers takes 30 seconds to a minute to extract.
I am a bit at a loss here. How do I do this using bitwise operators?
Thanks a lot!
I assume you have an understanding of the basic bit operations and how to express them in Java.
Use a pencil to draw a synthetic picture of the problem
byte 0 byte 1 byte 2 byte 3
01010110 01110100 00100101 01001011
\__/\__/ \__/\______/\___/\______/\___/
a b c d e f g
To extract a, b and c we need to do the following
a b c
byte 0 byte 0 byte 1
01010110 01010110 01110100
\. \. |||||||| \. \.
'\ '\ XXXX|||| '\ '\
0.. 0101 0.. 0110 0.. 0111
Shift And Shift
In Java
int a = byteArray[0] >>> 4, b = byteArray[0] & 0xf, c = byteArray[1] >>> 4;
The other values d, e, f and g are computed similarly but some of them require to read two bytes from the array (d and f actually).
d e
byte 1 byte 2 byte 2
01110100 00100101 00100101
||||\\\\ | |\\\\\
XXXX \\\\ | X \\\\\
\\\\| \\\\\
0.. 01000 01001
To compute d we need to isolate the least four bits of byte 1 with byteArray[1] & 0xf then make space for the bit from byte 2 with (byteArray[1] & 0xf) << 1, extract that bit with byteArray[1] >>> 7 and finally merge together the result.
int d = (byteArray[1] & 0xf) << 1 | byteArray[2] >>> 7;
int e = (byteArray[2] & 0x7c) >>> 2;
int f = (byteArray[2] & 0x3) << 3 | byteArray[3] >>> 5;
int g = byteArray[3] & 0x1f;
When you are comfortable with handling bits operations you may consider generalizing the function that extract the integers.
I made function int extract(byte[] bits, int[] sizes, int[] res), that given an array of bytes bits, an array of sizes sizes, where the even indices hold the size of the integers to extract in bits and the odd indices the number of integers to extract, and an output array res large enough to hold all the integers in output, extracts from bits all the integers expressed by sizes.
It returns the number of integers extracted.
For example the original problem can be solved as
int res[] = new int[8];
byte bits[] = new byte[]{0x56, 0x74, 0x25, 0x4b};
//Extract 3 integers of 4 bits and 4 integers of 5 bits
int ints = BitsExtractor.extract(bits, new int[]{4, 3, 5, 4}, res);
public class BitsExtractor
{
public static int extract(byte[] bits, int[] sizes, int[] res)
{
int currentByte = 0; //Index into the bits array
int intProduced = 0; //Number of ints produced so far
int bitsLeftInByte = 8; //How many bits left in the current byte
int howManyInts = 0; //Number of integers to extract
//Scan the sizes array two items at a time
for (int currentSize = 0; currentSize < sizes.length - 1; currentSize += 2)
{
//Size, in bits, of the integers to extract
int intSize = sizes[currentSize];
howManyInts += sizes[currentSize+1];
int temp = 0; //Temporary value of an integer
int sizeLeft = intSize; //How many bits left to extract
//Do until we have enough integer or we exhaust the bits array
while (intProduced < howManyInts && currentByte <= bits.length)
{
//How many bit we can extract from the current byte
int bitSize = Math.min(sizeLeft, bitsLeftInByte); //sizeLeft <= bitsLeftInByte ? sizeLeft : bitsLeftInByte;
//The value to mask out the number of bit extracted from
//The current byte (e.g. for 3 it is 7)
int byteMask = (1 << bitSize) - 1;
//Extract the new bits (Note that we extract starting from the
//RIGHT so we need to consider the bits left in the byte)
int newBits = (bits[currentByte] >>> (bitsLeftInByte - bitSize)) & byteMask;
//Create the new temporary value of the current integer by
//inserting the bits in the lowest positions
temp = temp << bitSize | newBits;
//"Remove" the bits processed from the byte
bitsLeftInByte -= bitSize;
//Is the byte has been exhausted, move to the next
if (bitsLeftInByte == 0)
{
bitsLeftInByte = 8;
currentByte++;
}
//"Remove" the bits processed from the size
sizeLeft -= bitSize;
//If we have extracted all the bits, save the integer
if (sizeLeft == 0)
{
res[intProduced++] = temp;
temp = 0;
sizeLeft = intSize;
}
}
}
return intProduced;
}
}
Well I did the first group , the second can be done in similar fashion
public static void main(String args[]) {
//an example 32 bits like your example
byte[] bytes = new byte[4];
bytes[0] = 31;//0001 1111
bytes[1] = 54;//0011 0110
bytes[2] = 67;
bytes[3] = 19;
//System.out.println(bytes[0]);
int x = 0;
int j = -1; // the byte number
int k = 0; // the bit number in that byte
int n = 0; // the place of the bit in the integer we are trying to read
for (int i = 0; i < 32; i++) {
if (i < 12) { //first group
if (i % 8 == 0) {
j++;
k = 0;
}
if (i % 4 == 0) {
x = 0;
n = 0;
}
byte bit = (byte) ((bytes[j] & (1 << (7 - k))) >> (7 - k));
System.out.println("j is :" + j + " k is :" + k + " " + bit);
x = x | bit << (3 - n);
if ((i + 1) % 4 == 0) {
System.out.println(x);
}
k++;
n++;
} else {
}
}
}
It's a bit tricky because you are trying to encode an integer on less than what java allocates (8 bits). So I had to take each bit and "construct" the int from them
To get each bit
byte bit = (byte) ((bytes[j] & (1 << (7 - k))) >> (7 - k));
this takes the byte we are at and does And operation. For example I want the 3rd bit of the 1st byte, I do
bytes[0] & 1 << (7 - 3)
but this gives me an integer encoded over 8 bits, so I still have to shift it to get that single bit with >> (7 - 3)
Then I just Or it with x (the int we are trying to decode). All while putting it at the right position with << (3 - n) . 3 because your integer is encoded over 4 bits
Try running the code and reading the output.
I am honestly not sure if this is the best way, but I believe it's at least faster than dealing with Strings

How can I split binary into 4 bytes sections?

I have a char holding different characters, and I would like to print the binary value of these into two 4 bytes sections. I am adding a 1 at the beginning so that they would be 4 each.
System.out.println(1 + Integer.toString(mychar[i],2));
I am using a for loop to go through the different characters and create a table. By doing this I can get the binary value plus the one. But i don't know how to separate it into two 4 bytes.
Lets assume that mychar[i] holds the String bryan. The output should be the following.
b 1110 0010
r 1111 0010
y 1111 1001
a 1110 0001
n 1110 1110
My personal favorite for zero-padding a small number (that is, a byte, a short etc) when converted to binary is:
String binaryRep = Integer.toBinaryString( 0x100 | mychar[i] & 0xff ).substring(1);
The & makes sure that no more than 8 bits are taken from mychar[i]
The 0x100 | part sets the 9th bit. This means all the zeros in the rightmost 8 bits will be represented in the result, which will be exactly 9 characters long.
Then taking the substring from 1 makes sure we take just the 8.
Of course, the above assumes a character that fits into 8 bits. If you try a Chinese or Arabic character it will basically just give you its rightmost 8 bits.
Whatever method you use for producing 8 zero-padded bits, you'll need to add the space in the middle. For my method above, we can make this modification:
public static String eightBitCharToBinary( char c ) {
String charAsNineBits = Integer.toBinaryString( 0x100 | c & 0xff );
return charAsNineBits.substring(1,5) + " " + charAsNineBits.substring(5,9);
}
Which does the same as above, but instead of just taking one substring, takes two substrings and puts a space in the middle.
I've used this answer to come to a solution:
private static String toBinaryRepresentation(String name) {
// 11 is size of "0000 0000\r\n
StringBuilder sb = new StringBuilder(name.length() * 11);
for (int i = 0; i < name.length(); i++) {
String binRep = toBinaryRepresentation(name.charAt(i));
sb.append(String.format("%s%n", binRep));
}
return sb.toString();
}
private static String toBinaryRepresentation(char c) {
if (c > 0xFF) {
throw new IllegalArgumentException("Character value too high to print");
}
int highNibble = (c >> 4) & 0xF;
String highBinaryDigits = String.format("%4s", Integer.toBinaryString(highNibble)).replace(' ', '0');
int lowNibble = c & 0xF;
String lowBinaryDigits = String.format("%4s", Integer.toBinaryString(lowNibble)).replace(' ', '0');
return String.format("%s %s", highBinaryDigits, lowBinaryDigits);
}
Which you can use by calling the function like this:
String name = "brian";
System.out.print(toBinaryRepresentation(name));
This prints:
0110 0010
0111 0010
0110 1001
0110 0001
0110 1110
So this first separates the high and low nibble and then prints the value using precisely 4 bits, even if they are zero.
public static void main(String []args){
String [] mychar = {"bryan"};
int len = mychar.length;
// iterate over each mychar element
for(int i =0; i< len ; i++){
// get the first string from array
String s = mychar[i];
int length = s.length();
//iterate over the string
for(int j =0; j< length ; j++){
char ch = s.charAt(j);
String str = Integer.toBinaryString(ch);
// print each char
System.out.print(ch+" : ");
System.out.println(str.substring(0,4)+" "+str.substring(3) );
}
}
}
char c = 'b';
String binaryString =Integer.toBinaryString(c);
System.out.println("1" + binaryString.substring(0, 3) + " " + binaryString.substring(3));

Algorithm to convert a String of decimal digits to BCD

I am looking a way to convert a string to BCD equivalent. I use Java, but it is not a question of the language indeed. I am trying to understand step by step how to convert a string to BCD.
For example, suppose I have the following string;
"0200" (This string has four ASCII characters, if we were in java this string had been contained in a byte[4] where byte[0] = 48, byte[1] = 50, byte[2] = 48 and byte[3] = 48)
In BCD (according this page: http://es.wikipedia.org/wiki/Decimal_codificado_en_binario):
0 = 0000
2 = 0010
0 = 0000
0 = 0000
Ok, I think the conversion is correct but I have to save this in a byte[2]. What Should I have to do? After, I have to read the BCD and convert it to the original string "0200" but first I have to resolve String to BCD.
Find a utility class to do this for you. Surely someone out there has written a BCD conversion utility for Java.
Here you go. I Googled "BCD Java" and got this as the first result. Copying code here for future reference.
public class BCD {
/*
* long number to bcd byte array e.g. 123 --> (0000) 0001 0010 0011
* e.g. 12 ---> 0001 0010
*/
public static byte[] DecToBCDArray(long num) {
int digits = 0;
long temp = num;
while (temp != 0) {
digits++;
temp /= 10;
}
int byteLen = digits % 2 == 0 ? digits / 2 : (digits + 1) / 2;
boolean isOdd = digits % 2 != 0;
byte bcd[] = new byte[byteLen];
for (int i = 0; i < digits; i++) {
byte tmp = (byte) (num % 10);
if (i == digits - 1 && isOdd)
bcd[i / 2] = tmp;
else if (i % 2 == 0)
bcd[i / 2] = tmp;
else {
byte foo = (byte) (tmp << 4);
bcd[i / 2] |= foo;
}
num /= 10;
}
for (int i = 0; i < byteLen / 2; i++) {
byte tmp = bcd[i];
bcd[i] = bcd[byteLen - i - 1];
bcd[byteLen - i - 1] = tmp;
}
return bcd;
}
public static String BCDtoString(byte bcd) {
StringBuffer sb = new StringBuffer();
byte high = (byte) (bcd & 0xf0);
high >>>= (byte) 4;
high = (byte) (high & 0x0f);
byte low = (byte) (bcd & 0x0f);
sb.append(high);
sb.append(low);
return sb.toString();
}
public static String BCDtoString(byte[] bcd) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bcd.length; i++) {
sb.append(BCDtoString(bcd[i]));
}
return sb.toString();
}
}
There's also this question: Java code or lib to decode a binary-coded decimal (BCD) from a String.
The first step would be to parse the string into an int so that you have the numeric value of it. Then, get the individual digits using division and modulus, and pack each pair of digits into a byte using shift and add (or shift and or).
Alternatively, you could parse each character of the string into an int individually, and avoid using division and modulus to get the numbers, but I would prefer to parse the entire string up front so that you discover right away if the string is invalid. (If you get a NumberFormatException, or if the value is less than 0 or greater than 9999 then it is invalid.)
Finally, once you have assembled the two individual bytes, you can put them into the byte[2].
You can use following:
//Convert BCD String to byte array
public static byte[] String2Bcd(java.lang.String bcdString) {
byte[] binBcd = new byte[bcdString.length() / 2];
for (int i = 0; i < binBcd.length; i++) {
String sByte = bcdString.substring(i*2, i*2+2);
binBcd[i] = Byte.parseByte(sByte, 16);
}
return binBcd;
}
You can try the following code:
public static byte[] hex2Bytes(String str) {
byte[] b = new byte[str.length() / 2];
int j = 0;
for (int i = 0; i < b.length; i++) {
char c0 = str.charAt(j++);
char c1 = str.charAt(j++);
b[i] = ((byte) (parse(c0) << 4 | parse(c1)));
}
return b;
}

Integer to two digits hex in Java

I need to change a integer value into 2-digit hex value in Java.Is there any way for this.
Thanks
My biggest number will be 63 and smallest will be 0.
I want a leading zero for small values.
String.format("%02X", value);
If you use X instead of x as suggested by aristar, then you don't need to use .toUpperCase().
Integer.toHexString(42);
Javadoc: http://docs.oracle.com/javase/6/docs/api/java/lang/Integer.html#toHexString(int)
Note that this may give you more than 2 digits, however! (An Integer is 4 bytes, so you could potentially get back 8 characters.)
Here's a bit of a hack to get your padding, as long as you are absolutely sure that you're only dealing with single-byte values (255 or less):
Integer.toHexString(0x100 | 42).substring(1)
Many more (and better) solutions at Left padding integers (non-decimal format) with zeros in Java.
String.format("%02X", (0xFF & value));
Use Integer.toHexString(). Dont forget to pad with a leading zero if you only end up with one digit. If your integer is greater than 255 you'll get more than 2 digits.
StringBuilder sb = new StringBuilder();
sb.append(Integer.toHexString(myInt));
if (sb.length() < 2) {
sb.insert(0, '0'); // pad with leading zero if needed
}
String hex = sb.toString();
If you just need to print them try this:
for(int a = 0; a < 255; a++){
if( a % 16 == 0){
System.out.println();
}
System.out.printf("%02x ", a);
}
i use this to get a string representing the equivalent hex value of an integer separated by space for every byte
EX : hex val of 260 in 4 bytes = 00 00 01 04
public static String getHexValString(Integer val, int bytePercision){
StringBuilder sb = new StringBuilder();
sb.append(Integer.toHexString(val));
while(sb.length() < bytePercision*2){
sb.insert(0,'0');// pad with leading zero
}
int l = sb.length(); // total string length before spaces
int r = l/2; //num of rquired iterations
for (int i=1; i < r; i++){
int x = l-(2*i); //space postion
sb.insert(x, ' ');
}
return sb.toString().toUpperCase();
}
public static void main(String []args){
System.out.println("hex val of 260 in 4 bytes = " + getHexValString(260,4));
}
According to GabrielOshiro, If you want format integer to length 8, try this
String.format("0x%08X", 20) //print 0x00000014

Categories