Anyone know what follow code does?
the question is about follow operators: & and |,and 0xfc
salt[0] = (byte)((salt[0] & 0xfc) | (saltLen & 0x03));
salt[1] = (byte)((salt[1] & 0xf3) | (saltLen & 0x0c));
salt[2] = (byte)((salt[2] & 0xcf) | (saltLen & 0x30));
salt[3] = (byte)((salt[3] & 0x3f) | (saltLen & 0xc0));
the question is about follow operators: & and |,and 0xfc
& is the bitwise and operator. See http://msdn.microsoft.com/en-us/library/sbf85k1c.aspx.
| is the bitwise or operator. See http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx.
0xfc isn't an operator, it's an integer constant (i.e., a number). See http://msdn.microsoft.com/en-us/library/aa664674(VS.71).aspx and http://en.wikipedia.org/wiki/Hexadecimal.
Well the comment above explains what it's doing, but if you're looking for a breakdown of the operators:
Perform a bitwise and on
salt[i] and a hex number (the & operator).
Perform a bitwise and on salt[i]
and a second hex number.
Perform a bitwise or on the result of steps 1 and 2 (the | operator).
Cast the result of step 3 to a byte
Store the result in salt[i]
The result is what is noted in the comment block. The numbers of the format 0xc0 and whatnot are in hexadecimal, which is base 16. I.e. c0 in hex is equivalent to 16*12 + 16*0 = 192 in decimal. In hex, since you run out of digits at 9, you begin using letters. Thus, a=10, b=11, c=12, d=13, e=14, f=15, and f becomes the highest "digit" since you would move over by one place when you get to 16 (as 16 is the base).
See also:
Bitwise operation
Hexadecimal
// Split salt length (always one byte) into four two-bit pieces and
// store these pieces in the first four bytes of the salt array.
This is a cocky answer, but my intention is to indicate that it is already answered, so please let me know if you need more detail :)
Related
I'm converting a Java library over to C# as I rewrite a legacy application and I need some assistance. I need to understand what this line in Java is doing:
sb.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1,3))
and if this C# line is equivalent
result += (Convert.ToInt32(b).ToString("x2") + " ").Substring(1,3);
In both cases b is a byte from a SHA-1 hash that the code is looping through.
The Java part I don't understand is ((b & 0xFF) | 0x100). It looks like it's padding it?
Ordinarily I would compare the output from the Java application to what my C# is generating but I am not in a postition to do that right now (and it's frustrating me - trust me).
You don't need to change the original that drastically - the C# equivalent (assuming 'sb' is a StringBuilder) is just:
sb.Append(((b & 0xFF) | 0x100).ToString("x").Substring(1, 2));
b & 0xFF will mask the lowest byte. So whatever b is, you will get something between 0x00 and 0xFF.
In the resulting integer, 9th bit is set, no matter what it was before. So you'll have something between 0x0100 to 0x01FF.
From that string the substring from index 1 to 3 is cropped. It will give you the last two digits which will be something between 00 and FF. The |0x100 is a neat trick to have Integer.toHexString give you a leading zero for the last two digits which it wouldn't according to it's javadoc ...
If I remeber correctly, your C# code does not exactly the same. But I hope with this explanation you can build it up yourself :)
I recently had a test question:
byte a,b,c;
a = 190;
b = 4;
c = (byte)(a & b);
What is the value of c?
I have never used a logical operand in this manner, what's going on here? Stepping through this, the answer is 4, but why?
Also, where would this come up in the real world? I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
You are doing a bitwise AND in this case, not a logical AND, it is combining the bits of the two values of a & b and giving you a result that has only the bits set that are both set in a & b, in this case, just the 4s place bit.
190 = 10111110
& 4 = 00000100
-------------------
= 4 00000100
Edit: Interestingly, msdn itself makes the issue of whether to call it logical vs bitwise a bit muddy. On their description of the logical operators (& && | || etc) they say logical operators (bitwise and bool) but then on the description of & itself it indicates it performs a bitwise AND for integers and a logical AND for bools. It appears it is still considered a logical operator, but the action between integer types is a bitwise AND.
http://msdn.microsoft.com/en-us/library/sbf85k1c(v=vs.71).aspx
The logical AND operator, when applied to integers performs a bitwise AND operation. The result is 1 in each position in which a 1 appears in both of the operands.
0011
& 0101
------
0001
The decimal value 190 is equivalent to binary 10111110. Decimal 4 is binary 00000100.
Do a logical AND operation on the bits like this:
10111110
& 00000100
----------
00000100
So the result is 4.
Also, where would this come up in the real world? I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
These operations are useful in several circumstances. The most common is when using Enum values as flags.
[Flags]
public enum MyFileOptions
{
None = 0,
Read = 1, // 2^0
Write = 2, // 2^1
Append = 4, // 2^2
}
If an Enum has values that are powers of two, then they can be combined into a single integer variable (with the Logical OR operator).
MyFileOptions openReadWrite = MyFileOptions.Read | MyFileOptions.Write;
In this variable, both bits are set, so it indicates that both the Read and Write options are selected.
The logical AND operator can be used to test values.
bool openForWriting = ((openReadWrite & MyFileOptions.Write) == MyFileOptions.Write);
NOTE
A lot of people are pointing out that this is actually a bitwise AND not a logical AND. I looked it up in the spec before I posted, and I was suprised to learn that both versions are referred to as "Logical AND" in the spec. This makes sense because it is performing the logical AND operation on each bit. So you are actually correct in the title of the question.
This is a bitwise AND, meaning the bits on both bytes are compared, and a 1 is returned if both bits are 1.
10111110 &
00000100
--------
00000100
One of the uses of a logical & on bytes is in networking and is called the Binary And Test. Basically, you logical and bytes by converting them to binary and doing a logical and on every bit.
In binary
4 == 100
190 == 10111110
& is and AND operation on the boolean operators, so it does de Binary and on 4 and 190 in byte format, so 10111110 AND 100 gives you 100, so the result is 4.
This is a bitwise AND, not a logical AND. Logical AND is a test of a condition ie:
if(a && b) doSomething();
A bitwise AND looks at the binary value of the two variables and combines them. Eg:
10101010 &
00001000
---------
00001000
This lines up the binary of the two numbers, like this:
10111110
00000100
--------
00000100
On each column, it checks to see if both numbers are 1. If it is, it will return 1 on the bottom. Otherwise, it will return 0 on the bottom.
I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
There is no cast. & is defined on integers, and intended to be used this way. And just so everyone knows, this technically is a logical operator according to MSDN, which I find kind of crazy.
I was doing some basic audio programming in C# using the NAudio package and I came across the following expression and I have no idea what it means, as i've never seen the << operator being used before. So what does << mean?
Please give a quick explaination of this expression.
short sample = (short)((buffer[index + 1] << 8) | buffer[index + 0]);
Definition
The left-shift operator (<<) shifts
its first operand left by the number
of bits specified by its second
operand. The type of the second
operand must be an int.
<< Operator (MSDN C# Reference)
For binary numbers it is a bitwise operation that shifts all of the bits of its operand; every bit in the operand is simply moved a given number of bit positions, and the vacant bit-positions are filled in.
Usage
Arithmetic shifts can be useful as efficient ways of performing multiplication or division of signed integers by powers of two. Shifting left by n bits on a signed or unsigned binary number has the effect of multiplying it by 2n. Shifting right by n bits on a two's complement signed binary number has the effect of dividing it by 2n, but it always rounds down (towards negative infinity). This is different from the way rounding is usually done in signed integer division (which rounds towards 0). This discrepancy has led to bugs in more than one compiler.
An other usage is work with color bits. Charles Petzold Foundations article "Bitmaps And Pixel Bits" shows an example of << when working with colors:
ushort pixel = (ushort)(green << 5 | blue);
Shift left (and the counterpart, Shift right) moves the bits in the given direction.
Shift left is more or less times 2, but faster
Shift right is more or less divided by 2, but faster
It's a left bit shift operation, a VERY common programming idiom: http://en.wikipedia.org/wiki/Arithmetic_shift
It's called left-shift operator.
Follow this link for more detailed information.
The bitwise operator has already been explained quite a few times already. Let's say that buffer[0] contains 1, buffer[1] contains 2 and index is 0 and replace these values:
short sample = (short)((buffer[1] << 8) | buffer[0]);
short sample = (short)((1 << 8) | 2);
Now, a semi-graphical representation. This is the numeral 1 in a binary representation:
0000 0001
Shifting eight positions to the left would make this number to "overflow" from a single byte. However, the compiler is smart enough to give us more room.
0000 0001 0000 0000
Now, the right part: the number 2 looks like this in binary:
0000 0010
And the "|" operator (bitwise OR) makes just put the two values together and comparing bit per bit.
0000 0001 0000 0000
| 0000 0000 0000 0010
= 0000 0001 0000 0010
And the final value is stored in your "sample" variable (in this case, 258.) The reverse operation is similar:
buffer[0] = sample & 255;
buffer[1] = (sample & (255 << 8)) >> 8;
Left shift
Here is some msdn to help you : http://msdn.microsoft.com/en-us/library/ayt2kcfb(VS.80).aspx
The "<<" is a shift left operator. x << y shifts bit pattern x y position left.
For example, if x was 0001 0101 and y was 1 then the result would be 0010 1010. It's like someone's pushed each bit left one.
As a few people have pointed out already it is a shift operation.
However It is worth noting that depending on whether the operand is a signed integral type or a unsigned integral type it will apply either an arithmetic or logical shift.
See the bottom of this page on msdn.
As others have said the << operator moves the bits of a number left. The normal reason why someone would do this in an Audio application is to combine two 8bit mono-samples (one for left and right) into a 16 bit sterio sample.
So in the sample code it looks like Buffer contains sterio encoded with left and right in alternate samples. By shifting the first left 8 and oring the second the author is combining them to form a 16bit sterio sample with the High 8bits being one channel and the low 8bits being the other.
If in your example the buffer contained:
1001 0100 (Right)
1001 0011 (Left)
The result you would get in sample is:
(Left) (Right)
1001 0011 1001 0100
I need to come up with a way to unpack a date into a readable format. unfortunately I don't completely understand the original process/code that was used.
Per information that was forwarded to me the date was packed using custom C/Python code as follows;
date = year << 20;
date |= month << 16;
date |= day << 11;
date |= hour << 6;
date |= minute;
For example, a recent packed date is 2107224749 which equates to Tuesday Sept. 22 2009 10:45am
I understand....or at least I am pretty sure....the << is shifting the bits but I am not sure what the "|" accomplishes.
Also, in order to unpack the code the notes read as follows;
year = (date & 0xfff00000) >> 20;
month = (date & 0x000f0000) >> 16;
day = (date & 0x0000f800) >> 11;
hour = (date & 0x000007c0) >> 6;
minute = (date & 0x0000003f);
Ultimately, what I need to do is perform the unpack and convert to readable format using either JavaScript or ASP but I need to better understand the process above in order to develop a solution.
Any help, hints, tips, pointers, ideas, etc. would be greatly appreciated.
The pipe (|) is bitwise or, it is used to combine the bits into a single value.
The extraction looks straight-forward, except I would recommend shifting first, and masking then. This keeps the constant used for the mask as small as possible, which is easier to manage (and can possibly be a tad more efficient, although for this case that hardly matters).
Looking at the masks used written in binary reveals how many bits are used for each field:
0xfff00000 has 12 bits set, so 12 bits are used for the year
0x000f0000 has 4 bits set, for the month
0x0000f800 has 5 bits set, for the day
0x000007c0 has 5 bits set, for the hour
0x0000003f has 6 bits set, for the minute
The idea is exactly what you said. Performing "<<" just shifts the bits to the left.
What the | (bitwise or) is accomplishing is basically adding more bits to the number, but without overwriting what was already there.
A demonstration of this principle might help.
Let's say we have a byte (8 bits), and we have two numbers that are each 4 bits, which we want to "put together" to make a byte. Assume the numbers are, in binary, 1010, and 1011. So we want to end up with the byte: 10101011.
Now, how do we do this? Assume we have a byte b, which is initialized to 0.
If we take the first number we want to add, 1010, and shift it by 4 bits, we get the number 10100000 (the shift adds bytes to the right of the number).
If we do: b = (1010 << 4), b will have the value 10100000.
But now, we want to add the 4 more bits (0011), without touching the previous bits. To do this, we can use |. This is because the | operator "ignores" anything in our number which is zero. So when we do:
10100000 (b's current value)
|
00001011 (the number we want to add)
We get:
10101011 (the first four numbers are copied from the first number,
the other four numbers copied from the second number).
Note: This answer came out a little long, I'm wikiing this, so, if anyone here has a better idea how to explain it, I'd appreciate your help.
These links might help:
http://www.gamedev.net/reference/articles/article1563.asp
http://compsci.ca/v3/viewtopic.php?t=9893
In the decode section & is bit wise and the 0xfff00000 is a hexadecimal bit mask. Basically each character in the bit mask represents 4 bits of the number. 0 being 0000 in binary and f being 1111 so if you look at the operation in binary you are anding 1111 1111 1111 0000 0000 ... with whatever is in date so basically you are getting the upper three nibbles(half bytes) and shifting them down so that 00A00000 gives you 10(A in hex) for the year.
Also note that |= is like += it is bit wise or then assignment rolled in to one.
Just to add some practical tips:
minute = value & ((1 << 6)-1);
hour = (value >> 6) & ((1<<5)-1); // 5 == 11-6 == bits reserved for hour
...
1 << 5 creates a bit at position 5 (i.e. 32=00100000b),
(1<<5)-1 cretaes a bit mask where the 5 lowest bits are set (i.e. 31 == 00011111b)
x & ((1<<5)-1) does a bitwise 'and' preserving only the bits set in the lowest five bits, extracting the original hour value.
Yes the << shifts bits and the | is the bitwise OR operator.
Continuing my previous question
Why I cannot derive from long?
I found an interesting problem.
Step one:
4294967296 & 0xFFFFFFFF00000000
Result: 4294967296.
Step two.
4294967296 & 0x00000000FFFFFFFF
Result: 0
Aha, So here I assume that 4294967296 == 0xFFFFFFFF
Let's check
(long)0x00000000FFFFFFFF
Result: 4294967295. Fail.
Let's double check
4294967296 >> 32
Result: 1. Fail.
The only explanation is that because i am using long where
some bit is reserved for sign. In C I would use unsigned long.
What do you think guys?
4294967296 & 0xFFFFFFFF00000000 = 4294967296
This indicates that the value 4294967296 has no bits set in the lower 32-bits. In fact, 4294967296 is 0x100000000, so this is true.
4294967296 >> 32 = 1
Again, consistent.
In other words, your conclusion that 4294967296 is 0xFFFFFFFF is wrong so the remaining checks will not support this.
Um... I'm not sure why you came to the conclusions you did but 4294967296 is 0x100000000. To write out the bitwise AND's in easily readable hex...
0x0000000100000000 &
0x00000000FFFFFFFF =
0x0000000000000000
0x0000000100000000 &
0xFFFFFFFF00000000 =
0x0000000100000000
Both of those make perfect sense. Perhaps you're misunderstanding a bitwise AND... it maps the bits that are the same in both. Your comments seem more appropriate to a bitwise XOR than a bitwise AND (Which is not the operation you're using)...
I think you are failing to understand the bitwise and operation. The bitwise and will return the bits that are set in both. If the two were the same then
(4294967296 & 0xFFFFFFFF00000000) == 4294967296
and
(4294967296 & 0xFFFFFFFF00000000) == 0xFFFFFFFF00000000
would both hold, but they obviously don't.