How can I make the Java code to calculate hexadecimal multiplication? (Just 8bit length.)
For example I have hexadecimal ab and 05, And F0 * 02 = fb (maybe).
But I don't know why the answer is fb.
Could you teach me how to make this with java code?
By hand, hexadecimal is base-16, so:
Hex Decimal
base 16 base 10
0 = 0
1 = 1
2 = 2
...
9 = 9
A = 10
B = 11
C = 12
D = 13
E = 14
F = 15
so the hexadecimal value AB is ((A = 10) * 16) + (B = 11)) or 160 + 11 == 171.
Bringing "8 bits" into the picture, a single byte (by convention these days, an octet) is made up of 8 bits. Eight bits is enough to represent 256 unique values, and in unsigned form represents values 0-255 decimal, or 0x00 to 0xFF hexadecimal. You may notice that this means that any 8-bit value can be represented by exactly two(2) hexadecimal digits.
In code, you can use 0x prefix to enter literals in hexadecimal notation.
int answer = 0xF0 * 0x02;
System.out.printf("%x%n", answer);
A Formatter (or similar, like System.out.printf) can convert a result back into hex easily enough. But if this is for a homework assignment, your instructor won't like this answer.
Related
Recently I have been going through some examples of MD5 to start getting an understanding of security and MD5 has been fairly simple to understand for the most part and a good starting point even though it is no longer secure. Despite this I have a question regarding high and lo nibbles when it comes to converting a string to a hex string.
So I know high and low nibbles are equal to half a byte or also can be hex digits that represent a single hexadecimal digit. What I am not understanding though is exactly how they work and the purpose that they serve. I have been searching on google and I can't find much of an answer that will help explain what they do in the context that they are in. Here is the context of the conversion:
private static String toHexString( byte[] byteArray )
{
final String HEX_CHARS = "0123456789ABCDEF";
byte[] result = new byte[byteArray.length << 1];
int len = byteArray.length;
for( int i = 0 ; i < len ; i++ )
{
byte b = byteArray[i]
int lo4 = b & 0x0F;
int hi4 = ( b & 0xF0 ) >> 4;
result[i * 2] = (byte)HEX_CHARS.charAt( hi4 );
result[i * 2 + 1] = (byte)HEX_CHARS.charAt( lo4 );
}
return new String( result );
}
I don't exactly understand what is going on in the for statement. I would appreciate any help understanding this and if there is some link to some places that I can learn more about this please also leave it.
I understand the base definition of nibble but not the operations and what the assignment to the number 4 is doing either.
If I need to post the full example code I will just ask as I am unsure if it is needed.
This code simply converts a byte array to hexadecimal representation. Within the for-loop, each byte is converted into two characters. I think it's easier to understand it on an example.
Assume one of the bytes in your array is, say, 218 (unsigned). That's 1101 1010 in binary.
lo4 gets the lowest 4 bits by AND-ing the byte with the bitmask 00001111:
int lo4 = b & 0x0F;
This results in 1010, 10 in decimal.
hi4 gets the highest 4 bits by AND-ing with the bitmask 1111 0000 and shifting 4 bits to the right:
int hi4 = ( b & 0xF0 ) >> 4;
This results in 1101, 13 in decimal.
Now to get the hexadecimal representation of this byte you only need to convert 10 and 13 to their hexadecimal representations and concatenate. For this you simply look up the character in the prepared HEX_CHARS string at the specific index. 10 -> A, 13 -> D, resulting in 218 -> DA.
It's just bit operations. The & character takes the literal bit value of each and does a logical and on them.
int lo4 = b & 0x0F;
for instance if b = 24 then it will evaluate to this
00011000
+00001111
=00001000
The second such line does the same on the first four bits.
00011000
+11110000
=00010000
the '>>' shifts all of the bits a certain number in that direction so
00010000 >> 4 = 00000001.
This is done so that you can derive the hex value from the number. Since each character in hex can represent 4 bits by splitting the number into pieces of 4 bits we can convert it.
in the case of b = 24 we no have lo4 = 1000 or 8 and hi4 = 0001 or 1. The last part of the loop assigns the character value for each.
Hex_chars[hi4] = '1' and Hex_chars[lo4] = '8' which gives you "18" for that part of the string which is 24 in hex.
The output is 9 and I can't get my head around the whole bitwise XOR concept.
public class XOR {
public static void main( String[] args ) {
int a = 12;
int b = 5;
int c = a ^ b;
System.out.print( c );
}
}
XOR stands for exclusive or
Exclusive or or exclusive disjunction is a logical operation that outputs true only when inputs differ (one is true, the other is false)
in your case, it's a bitwise comparison, so each 0 and 1 at the same position is compared
first step is to translate values from decimal to binary
12 = 00001100
05 = 00000101
Then, you apply XOR
12 = 00001100
05 = 00000101
XOR = 00001001
Finally, you convert from binary to decimal
00001001 = 9
the XOR operator first converts both of your values into their binary equivalents. Binary operations will apply to corresponding bits, and the XOR operator evaluates to true (1) whenever the corresponding bits are not equal. For example, 2^1 = 3 [10 ^ 01] notice the first bits and the second bits are different, so both bits evaluate to 1.
In your example: 12 ^ 5
12 = 1 1 0 0
5 = 0 1 0 1
The first and the 4th bits are of opposite value, so the first and the fourth bits evaluate to 1, while the remaining bits evaluate to 0, so the solution is 1001 = 9
int i =132;
byte b =(byte)i; System.out.println(b);
Mindboggling. Why is the output -124?
In Java, an int is 32 bits. A byte is 8 bits .
Most primitive types in Java are signed, and byte, short, int, and long are encoded in two's complement. (The char type is unsigned, and the concept of a sign is not applicable to boolean.)
In this number scheme the most significant bit specifies the sign of the number. If more bits are needed, the most significant bit ("MSB") is simply copied to the new MSB.
So if you have byte 255: 11111111
and you want to represent it as an int (32 bits) you simply copy the 1 to the left 24 times.
Now, one way to read a negative two's complement number is to start with the least significant bit, move left until you find the first 1, then invert every bit afterwards. The resulting number is the positive version of that number
For example: 11111111 goes to 00000001 = -1. This is what Java will display as the value.
What you probably want to do is know the unsigned value of the byte.
You can accomplish this with a bitmask that deletes everything but the least significant 8 bits. (0xff)
So:
byte signedByte = -1;
int unsignedByte = signedByte & (0xff);
System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte);
Would print out: "Signed: -1 Unsigned: 255"
What's actually happening here?
We are using bitwise AND to mask all of the extraneous sign bits (the 1's to the left of the least significant 8 bits.)
When an int is converted into a byte, Java chops-off the left-most 24 bits
1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101
Since the 32nd bit is now the sign bit instead of the 8th bit (and we set the sign bit to 0 which is positive), the original 8 bits from the byte are read by Java as a positive value.
132 in digits (base 10) is 1000_0100 in bits (base 2) and Java stores int in 32 bits:
0000_0000_0000_0000_0000_0000_1000_0100
Algorithm for int-to-byte is left-truncate; Algorithm for System.out.println is two's-complement (Two's-complement is if leftmost bit is 1, interpret as negative one's-complement (invert bits) minus-one.); Thus System.out.println(int-to-byte( )) is:
interpret-as( if-leftmost-bit-is-1[ negative(invert-bits(minus-one(] left-truncate(0000_0000_0000_0000_0000_0000_1000_0100) [)))] )
=interpret-as( if-leftmost-bit-is-1[ negative(invert-bits(minus-one(] 1000_0100 [)))] )
=interpret-as(negative(invert-bits(minus-one(1000_0100))))
=interpret-as(negative(invert-bits(1000_0011)))
=interpret-as(negative(0111_1100))
=interpret-as(negative(124))
=interpret-as(-124)
=-124 Tada!!!
byte in Java is signed, so it has a range -2^7 to 2^7-1 - ie, -128 to 127.
Since 132 is above 127, you end up wrapping around to 132-256=-124. That is, essentially 256 (2^8) is added or subtracted until it falls into range.
For more information, you may want to read up on two's complement.
132 is outside the range of a byte which is -128 to 127 (Byte.MIN_VALUE to Byte.MAX_VALUE)
Instead the top bit of the 8-bit value is treated as the signed which indicates it is negative in this case. So the number is 132 - 256 = -124.
here is a very mechanical method without the distracting theories:
Convert the number into binary representation (use a calculator ok?)
Only copy the rightmost 8 bits (LSB) and discard the rest.
From the result of step#2, if the leftmost bit is 0, then use a calculator to convert the number to decimal. This is your answer.
Else (if the leftmost bit is 1) your answer is negative. Leave all rightmost zeros and the first non-zero bit unchanged. And reversed the rest, that is, replace 1's by 0's and 0's by 1's. Then use a calculator to convert to decimal and append a negative sign to indicate the value is negative.
This more practical method is in accordance to the much theoretical answers above. So, those still reading those Java books saying to use modulo, this is definitely wrong since the 4 steps I outlined above is definitely not a modulo operation.
Two's complement Equation:
In Java, byte (N=8) and int (N=32) are represented by the 2s-complement shown above.
From the equation, a7 is negative for byte but positive for int.
coef: a7 a6 a5 a4 a3 a2 a1 a0
Binary: 1 0 0 0 0 1 0 0
----------------------------------------------
int: 128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = 132
byte: -128 + 0 + 0 + 0 + 0 + 4 + 0 + 0 = -124
often in books you will find the explanation of casting from int to byte as being performed by modulus division. this is not strictly correct as shown below
what actually happens is the 24 most significant bits from the binary value of the int number are discarded leaving confusion if the remaining leftmost bit is set which designates the number as negative
public class castingsample{
public static void main(String args[]){
int i;
byte y;
i = 1024;
for(i = 1024; i > 0; i-- ){
y = (byte)i;
System.out.print(i + " mod 128 = " + i%128 + " also ");
System.out.println(i + " cast to byte " + " = " + y);
}
}
}
A quick algorithm that simulates the way that it work is the following:
public int toByte(int number) {
int tmp = number & 0xff
return (tmp & 0x80) == 0 ? tmp : tmp - 256;
}
How this work ? Look to daixtr answer. A implementation of exact algorithm discribed in his answer is the following:
public static int toByte(int number) {
int tmp = number & 0xff;
if ((tmp & 0x80) == 0x80) {
int bit = 1;
int mask = 0;
for(;;) {
mask |= bit;
if ((tmp & bit) == 0) {
bit <<=1;
continue;
}
int left = tmp & (~mask);
int right = tmp & mask;
left = ~left;
left &= (~mask);
tmp = left | right;
tmp = -(tmp & 0xff);
break;
}
}
return tmp;
}
If you want to understand this mathematically, like how this works
so basically numbers b/w -128 to 127 will be written same as their decimal value, above that its (your number - 256).
eg. 132, the answer will be
132 - 256 = - 124
i.e.
256 + your answer in the number
256 + (-124) is 132
Another Example
double a = 295.04;
int b = 300;
byte c = (byte) a;
byte d = (byte) b; System.out.println(c + " " + d);
the Output will be 39 44
(295 - 256) (300 - 256)
NOTE: it won't consider numbers after the decimal.
Conceptually, repeated subtractions of 256 are made to your number, until it is in the range -128 to +127. So in your case, you start with 132, then end up with -124 in one step.
Computationally, this corresponds to extracting the 8 least significant bits from your original number. (And note that the most significant bit of these 8 becomes the sign bit.)
Note that in other languages this behaviour is not defined (e.g. C and C++).
In java int takes 4 bytes=4x8=32 bits
byte = 8 bits range=-128 to 127
converting 'int' into 'byte' is like fitting big object into small box
if sign in -ve takes 2's complement
example 1: let number be 130
step 1:130 interms of bits =1000 0010
step 2:condider 1st 7 bits and 8th bit is sign(1=-ve and =+ve)
step 3:convert 1st 7 bits to 2's compliment
000 0010
-------------
111 1101
add 1
-------------
111 1110 =126
step 4:8th bit is "1" hence the sign is -ve
step 5:byte of 130=-126
Example2: let number be 500
step 1:500 interms of bits 0001 1111 0100
step 2:consider 1st 7 bits =111 0100
step 3: the remained bits are '11' gives -ve sign
step 4: take 2's compliment
111 0100
-------------
000 1011
add 1
-------------
000 1100 =12
step 5:byte of 500=-12
example 3: number=300
300=1 0010 1100
1st 7 bits =010 1100
remaining bit is '0' sign =+ve need not take 2's compliment for +ve sign
hence 010 1100 =44
byte(300) =44
N is input number
case 1: 0<=N<=127 answer=N;
case 2: 128<=N<=256 answer=N-256
case 3: N>256
temp1=N/256;
temp2=N-temp*256;
if temp2<=127 then answer=temp2;
else if temp2>=128 then answer=temp2-256;
case 4: negative number input
do same procedure.just change the sign of the solution
I need to write a converter in Java where it asks the user for an input, sourceAlphabet and targetAlphabet). The code should then provide an answer which has converted the sourceAlphabet to the targetAlphabet.
Alphabets should be given in the form:
-"0123456789" (Base 10),
-"abcdefghijklmnopqrstuvwxyz" (Alphabet),
-"0123456789ABCDEF" (Hexadecimal), etc.
Each alphabet value is a single unique ASCII character.
These are some sample inputs and answers I am looking for from the code:
convert("129","0123456789","01") === "10000001"
convert("FF","0123456789ABCDEF","0123456789") === "255"
convert("svip","abcdefghijklmnopqrstuvwxyz","0123456789ABCDEF") === "50C23"
Any help in getting me started on this problem would be greatly appreciated.
As a starting point, create a function that converts from decimal to hexadecimal.
The best tools to help you do this will be the modulo operator (x % y) and the division operator (x / y). Modulo (or mod) gives you the remainder, so if you imagine have a number like 24, 24 % 16 = 8, while 24 / 16 = 1. Notice that if I had 31 % 16, I would receive 15.
With those tools, you can operate on the input decimal and repeatedly mod by the base over the number to get the remainder, and then set the decimal equal to itself divided by the base.
For example.
Step 1.
Decimal : 31
String : ""
Base : 16
31 % 16 = 15
31 / 16 = 1
Step 2
Decimal : 1
String : "E"
Base : 16
1 % 16 = 1
1 / 16 = 1
Step 3
Decimal : 0
String :"1E"
Base : 16
Fin
Hope that helps.
I have the rather simple method naf
public int naf(int NN, int AA, int FF, int Q) {
int mike = FF + 0x20 * AA + 0x200 * NN;
if (Q == 1) {
mike += 0x4000;
}
return mike;
}
I can understand that this method accepts 4 integers and returns an integer. In the second line, the calculations are a bit confusing. I feel that the 0x parts have to do with hexadecimal number format, but the input arguments are in decimal. I have also the feeling that the 0x may make those calculations doable, but I am not certain.
What does the 0x offer and how can the method make hexadecimal calculations, when the input is decimal?
There's no such thing as hexadecimal calculations.
You have an integer expression, it is just that in it
two numbers are represented in hexadecimal format.
This
int mike = FF + 0x20*AA + 0x200 * NN;
is the same as:
int mike = FF + 2 * 16 * AA + 2 * 16 * 16 * NN;
which is the same as:
int mike = FF + 32 * AA + 512 * NN;
For a computer it doesn't matter how numbers are presented to you, be it decimal (base 10, as we're naturally familiar with), hexadecimal (base 16), octal (base 8), binary (base 2), you name it (though in Java only octal, decimal and hexadecimal are possible out of the box). Internally they are all stored as binary numbers, that's a series of zeros and ones.
In your code you are free to choose the format you feel most comfortable with. By default the Java compiler assumes you are feeding it decimal numbers, but by prefixing your number either with 0x or only 0 you tell it to interpret them as hexadecimal or octal numbers, respectively.
I suggest you try to read up on numeral systems.
Integer literals in java can be in the form of decimal (eg. 32), hexadecimal (eg. 0x20) and octal (eg. 040). The differences being decimal: no prefix, hexadecimal: prefix 0x and octal: prefix 0.
Thus,
int mike = FF + 0x20 * AA + 0x200 * NN;
is really just
int mike = FF + 32 * AA + 512 * NN;
Oh and the fact that FF is also on "hex form" doesn't matter at all, it's just a method parameter and might as well be called steven... :-)
Cheers,
Decimal or hexadecimal only applies when you express literals, e.g.:
int a = 0xfa; // hexadecimal notation for literal on the right hand side
int b = 251; // decimal notation for the literal on the right hand side
Once the values have been stored in variables the system doesn't care if you used decimal or hexadecimal notation to express the values that you stored:
int c = a + b; // numbers are added, regardless of you they were expressed above