Bit shifting confusion in C# - c#

I have some old code like this:
private int ParseByte(byte theByte)
{
byte[] bytes = new byte[1];
bytes[0] = theByte;
BitArray bits = new BitArray(bytes);
if (bits[0])
return 1;
else
return 0;
}
It's long and I figured I could trim it down like this:
private int ParseByte(byte theByte)
{
return theByte >> 7;
}
But, I'm not getting the same values as the first function. The byte either contains 00000000 or 10000000. What am I missing here? Am I using an incorrect operator?

The problem is that, in the first function, bits[0] returns the least significant bit, but the second function is returning the most significant bit. To modify the second function to get the least significant bit:
private int ParseByte(byte theByte)
{
return theByte & 00000001;
}
To modify the first function to return the most significant bit, you should use bits[7] -- not bits[0].

The equivalent function to the first snipet is:
return theByte & 1 == 1
In the second snipet you were chechink the most significative bit and in the first snipet the least significant.

Do you want to return int or string? Anyway - you can use modulo:
return theByte % 2 == 0 ? "0" : "1"
OK, you edited ... and want to return int
A word to your shifting operation: you would have to use << instead of >>. But this returns (when you cast to byte instead of int) 0 or 128 and not 0 or 1. So you could rewrite your second solution as:
return (byte)(theByte << 7) == 128 ? 1 : 0;
But the other answers contain really better solutions than this.

Perhaps the first function should check for bits[7] ?

You have an extra zero in your binary numbers (you have 9 digits in each). I'm assuming that's just a typo.
Are you sure you're doing your ordering correctly? Binary is traditionally written right-to-left, not left-to-right like most other numbering systems. If the binary number you showed is property formatted (meaning that 10000000 is really the number 128 and not the number 1) then your first code snippet shouldn't work and the second should. If you're writing it backwards (meaning 10000000 is 1, not 128), then you don't even need to bitshift. Just AND it with 1 (theByte & 1).
In fact, regardless of the approach a bitwise AND (the & operator) seems more appropriate. Given that your first function works and the second does not, I'm assuming you just wrote the number backwards and need to AND it with 1 as described above.

According to a user on Microsoft's site the BitArray internally stores the bits into Int32s in big endian in bit order. That could cause the problem. For a solution and further info you can visit the link.

1st The first function does not work as it tries to return a string instead of an int.
But what you might want is this:
private static int ParseByte(byte theByte)
{
return theByte & 1;
}
However you might also want this:
private static string ParseByteB(byte theByte)
{
return (theByte & 1).ToString();
}

Related

Microsoft BigInteger goes "negative" when I import from an array

Suppose I have an array that ends with the most signifiant bit of the most significant byte equaling 1.
My understanding is that if this is the case, BigInteger will treat this as a negative number, by design.
BigInteger numberToShorten = new BigInteger(toEncode);
if (numberToShorten.Sign == -1)
{
// problem with twos compliment or the last bit of the last byte is equal to 1
throw new Exception("Unexpected negative number");
}
To solve this problem, I think I need to add a dummy zero bit to the array, prior to converting the array. I can easily do this using Array.Resize().
My question is, how should I test if the last bit is indeed equal to 1?
I'm pretty weak on my boolean logic now, and am thinking I need to AND the values and test for equality, but not able to get the syntax correct in C#. Something like this:
byte temp = toEncode[toEncode.Length - 1];
if (temp == ???)
{
Array.Resize(ref toEncode, toEncode.Length +1);
}
If the number to be converted to BigInteger is always positive then you don't actually need to test at all; just appending a zero byte will always work correctly.
For completeness, checking if the MSB of any one byte is set is done with
if (byte & 0x80 == 0x80) ...
Found the answer at the bottom of this MSDN article (I think)
ulong originalNumber = UInt64.MaxValue;
byte[] bytes = BitConverter.GetBytes(originalNumber);
if (originalNumber > 0 && (bytes[bytes.Length - 1] & 0x80) > 0)
{
byte[] temp = new byte[bytes.Length];
Array.Copy(bytes, temp, bytes.Length);
bytes = new byte[temp.Length + 1];
Array.Copy(temp, bytes, temp.Length);
}
BigInteger newNumber = new BigInteger(bytes);
Console.WriteLine("Converted the UInt64 value {0:N0} to {1:N0}.",
originalNumber, newNumber);
// The example displays the following output:
// Converted the UInt64 value 18,446,744,073,709,551,615 to 18,446,744,073,709,551,615.
I'm not sure if this is necessary, have you tried it? In any case, assuming that temp contains a byte and you are trying to test whether that byte ends in 1, this is how you should do it:
if((temp & 0x01)==1)
{
...
}
That amounts to:
Temp: ???????z
0x01: 00000001
Temp & 0x01: 0000000z
Where z represents the bit you are trying to test, and you can now just test whether the result is equal to 1 or not.
If you are trying to test whether the byte starts with 1, do:
if((temp & 0x80)==0x80) //0x80 is 10000000 in binary
{
...
}

How to store integers efficiently in bytes ?

I'm looking for a good and efficient way to store integers in bytes.
The situation is the following:
I have two integers, Value 1 is "1857" (11bit) and Value 2 is "14" (4bit) and 2 bytes (16bit).
What I'm looking for, is to store the 2 integers in the 2 bytes. This mean cut the first integer, put 8 bits in the first byte and the rest plus the second integer in the second byte. Also I need to get them back together.
Is there a way or .net class to do that?
I've found the BitConverter class, but thats not what I'm looking for because this class only convert one integer to an full byte array.
You could use bit operators for that: bitwise and (&), or (|), and shift left (<<) and right (>>):
int value1 = 1857;
int value2 = 14;
int result = value1 | (value2 << 11);
To get the original values back you have to reverse that:
int result1 = result & 0x7ff; // 1857
int result2 = result >> 11; // 14

Cryptography .NET, Avoiding Timing Attack

I was browsing crackstation.net website and came across this code which was commented as following:
Compares two byte arrays in length-constant time. This comparison method is used so that password hashes cannot be extracted from on-line systems using a timing attack and then attacked off-line.
private static bool SlowEquals(byte[] a, byte[] b)
{
uint diff = (uint)a.Length ^ (uint)b.Length;
for (int i = 0; i < a.Length && i < b.Length; i++)
diff |= (uint)(a[i] ^ b[i]);
return diff == 0;
}
Can anyone please explain how does this function actual works, why do we need to convert the length to an unsigned integer and how this method avoids a timing attack? What does the line diff |= (uint)(a[i] ^ b[i]); do?
This sets diff based on whether there's a difference between a and b.
It avoids a timing attack by always walking through the entirety of the shorter of the two of a and b, regardless of whether there's a mismatch sooner than that or not.
The diff |= (uint)(a[i] ^ (uint)b[i]) takes the exclusive-or of a byte of a with a corresponding byte of b. That will be 0 if the two bytes are the same, or non-zero if they're different. It then ors that with diff.
Therefore, diff will be set to non-zero in an iteration if a difference was found between the inputs in that iteration. Once diff is given a non-zero value at any iteration of the loop, it will retain the non-zero value through further iterations.
Therefore, the final result in diff will be non-zero if any difference is found between corresponding bytes of a and b, and 0 only if all bytes (and the lengths) of a and b are equal.
Unlike a typical comparison, however, this will always execute the loop until all the bytes in the shorter of the two inputs have been compared to bytes in the other. A typical comparison would have an early-out where the loop would be broken as soon as a mismatch was found:
bool equal(byte a[], byte b[]) {
if (a.length() != b.length())
return false;
for (int i=0; i<a.length(); i++)
if (a[i] != b[i])
return false;
return true;
}
With this, based on the amount of time consumed to return false, we can learn (at least an approximation of) the number of bytes that matched between a and b. Let's say the initial test of length takes 10 ns, and each iteration of the loop takes another 10 ns. Based on that, if it returns false in 50 ns, we can quickly guess that we have the right length, and the first four bytes of a and b match.
Even without knowing the exact amounts of time, we can still use the timing differences to determine the correct string. We start with a string of length 1, and increase that one byte at a time until we see an increase in the time taken to return false. Then we run through all the possible values in the first byte until we see another increase, indicating that it has executed another iteration of the loop. Continue with the same for successive bytes until all bytes match and we get a return of true.
The original is still open to a little bit of a timing attack -- although we can't easily determine the contents of the correct string based on timing, we can at least find the string length based on timing. Since it only compares up to the shorter of the two strings, we can start with a string of length 1, then 2, then 3, and so on until the time becomes stable. As long as the time is increasing our proposed string is shorter than the correct string. When we give it longer strings, but the time remains constant, we know our string is longer than the correct string. The correct length of string will be the shortest one that takes that maximum duration to test.
Whether this is useful or not depends on the situation, but it's clearly leaking some information, regardless. For truly maximum security, we'd probably want to append random garbage to the end of the real string to make it the length of the user's input, so the time stays proportional to the length of the input, regardless of whether it's shorter, equal to, or longer than the correct string.
this version goes on for the length of the input 'a'
private static bool SlowEquals(byte[] a, byte[] b)
{
uint diff = (uint)a.Length ^ (uint)b.Length;
byte[] c = new byte[] { 0 };
for (int i = 0; i < a.Length; i++)
diff |= (uint)(GetElem(a, i, c, 0) ^ GetElem(b, i, c, 0));
return diff == 0;
}
private static byte GetElem(byte[] x, int i, byte[] c, int i0)
{
bool ok = (i < x.Length);
return (ok ? x : c)[ok ? i : i0];
}

How do I check for presence of a bit in C# using AND?

How to I use logical operators to determine if a bit is set, or is bit-shifting the only way?
I found this question that uses bit shifting, but I would think I can just AND out my value.
For some context, I'm reading a value from Active Directory and trying to determine if it a Schema Base Object. I think my problem is a syntax issue, but I'm not sure how to correct it.
foreach (DirectoryEntry schemaObjectToTest in objSchema.Children)
{
var resFlag = schemaObjectToTest.Properties["systemFlags"].Value;
//if bit 10 is set then can't be made confidential.
if (resFlag != null)
{
byte original = Convert.ToByte( resFlag );
byte isFlag_Schema_Base_Object = Convert.ToByte( 2);
var result = original & isFlag_Schema_Base_Object;
if ((result) > 0)
{
//A non zero result indicates that the bit was found
}
}
}
When I look at the debugger:
resFlag is an object{int} and the value is 0x00000010.
isFlag_Schema_Base_Object, is 0x02
resFlag is 0x00000010 which is 16 in decimal, or 10000 in binary. So it seems like you want to test bit 4 (with bit 0 being the least significant bit), despite your comment saying "if bit 10 is set".
If you do need to test bit 4, then isFlag_Schema_Base_Object needs to be initialised to 16, which is 0x10.
Anyway, you are right - you don't need to do bit shifting to see if a bit is set, you can AND the value with a constant that has just that bit set, and see if the result is non-zero.
If the bit is set:
original xxx1xxxx
AND
isFlag_Schema_Base_Object 00010000
-----------------------------------
= 00010000 (non-zero)
But if the bit isn't set:
original xxx0xxxx
AND
isFlag_Schema_Base_Object 00010000
-----------------------------------
= 00000000 (zero)
Having said that, it might be clearer to initialise isFlag_Schema_Base_Object using the value 1<<4, to make it clear that you're testing whether bit 4 is set.
If you know which bit to check and you're dealing with int's you can use BitVector32.
int yourValue = 5;
BitVector32 bv = new BitVector32(yourValue);
int bitPositionToCheck = 3;
int mask = Enumerable.Range(0, bitPositionToCheck).Select(BitVector32.CreateMask).Last();
bool isSet = bv[mask];
Using bitshifting is probably cleaner than using CreateMask. But it's there :)

how to loop through the digits of a binary number?

I have a binary number 1011011, how can I loop through all these binary digits one after the other ?
I know how to do this for decimal integers by using modulo and division.
int n = 0x5b; // 1011011
Really you should just do this, hexadecimal in general is much better representation:
printf("%x", n); // this prints "5b"
To get it in binary, (with emphasis on easy understanding) try something like this:
printf("%s", "0b"); // common prefix to denote that binary follows
bool leading = true; // we're processing leading zeroes
// starting with the most significant bit to the least
for (int i = sizeof(n) * CHAR_BIT - 1; i >= 0; --i) {
int bit = (n >> i) & 1;
leading |= bit; // if the bit is 1, we are no longer reading leading zeroes
if (!leading)
printf("%d", bit);
}
if (leading) // all zero, so just print 0
printf("0");
// at this point, for n = 0x5b, we'll have printed 0b1011011
You can use modulo and division by 2 exactly like you would in base 10. You can also use binary operators, but if you already know how to do that in base 10, it would be easier if you just used division and modulo
Expanding on Frédéric and Gabi's answers, all you need to do is realise that the rules in base 2 are no different to in base 10 - you just need to do your division and modulus with a divisor 2 instead of 10.
The next step is simply to use number >> 1 instead of number / 2 and number & 0x1 instead of number % 2 to improve performance. Mind you, with modern optimising compilers there's probably no difference...
Use an AND with increasing powers of two...
In C, at least, you can do something like:
while (val != 0)
{
printf("%d", val&0x1);
val = val>>1;
}
To expand on #Marco's answer with an example:
uint value = 0x82fa9281;
for (int i = 0; i < 32; i++)
{
bool set = (value & 0x1) != 0;
value >>= 1;
Console.WriteLine("Bit set: {0}", set);
}
What this does is test the last bit, and then shift everything one bit.
If you're already starting with a string, you could just iterate through each of the characters in the string:
var values = "1011011".Reverse().ToCharArray();
for(var index = 0; index < values.Length; index++) {
var isSet = (Boolean)Int32.Parse(values[index]); // Boolean.Parse only works on "true"/"false", not 0/1
// do whatever
}
byte input = Convert.ToByte("1011011", 2);
BitArray arr = new BitArray(new[] { input });
foreach (bool value in arr)
{
// ...
}
You can simply loop through every bit. The following C like pseudocode allows you to set the bit number you want to check. (You might also want to google endianness)
for()
{
bitnumber = <your bit>
printf("%d",(val & 1<<bitnumber)?1:0);
}
The code basically writes 1 if the bit it set or 0 if not. We shift the value 1 (which in binary is 1 ;) ) the number of bits set in bitnumber and then we AND it with the value in val to see if it matches up. Simple as that!
So if bitnumber is 3 we simply do this
00000100 ( The value 1 is shifted 3 left for example)
AND
10110110 (We check it with whatever you're value is)
=
00000100 = True! - Both values have bit 3 set!

Categories