0

I am working on a c# desktop application. I have a bit string and i want to toggle it.

c3 = DecimalToBinary(Convert.ToInt32(tbVal3.Text)).PadLeft(16, '0');
// above c3 is 0000001011110100

spliting the above string into two (substring)

string part1 = c3.Substring(0, 8); // 00000010

string part2 = c3.Substring(8, 8); // 11110100

For part1 the MSB of the first octet shall be set to 1 and for part2 thus this bit shall be shifted into the LSB of the first octet the MSB of the second (last) octet shall be set to 0,thus this bit shall be shifted into the LSB of the first octet. This gives binary part1 = 10000101 and part2 = 01110100

I have checked this solution Binary array after M range toggle operations but still, it's not understandable.

Rule

in the case of the application context name LN referencing with no ciphering 
the arc labels of the object identifier are (2, 16, 756, 5, 8, 1, 1);
• the first octet of the encoding is the combination of the first two 
 numbers into a single number, following the rule of 
 40*First+Second -> 40*2 + 16 = 96 = 0x60;
• the third number of the Object Identifier (756) requires two octets: its 
hexadecimal value is 0x02F4, which is 00000010 11110100, but following the above rule, 
the MSB of the first octet shall be set to 1 and the MSB of the second (last) octet shall 
be set to 0, thus this bit shall be shifted into the LSB of the first octet. This gives 
binary 10000101 01110100, which is 0x8574;
• each remaining numbers of the Object Identifier required to be encoded on one octet;
• this results in the encoding 60 85 74 05 08 01 01.

How can I perform this toggle with binary strings?

Any help would be highly appreciated

Moeez
  • 494
  • 9
  • 55
  • 147
  • You shouldn't be using `string` if you want to do binary operations. Use `byte`, `int`, or some other appropriate numeric type. Convert to a string only when you need to display the output. – Herohtar Oct 26 '19 at 04:12
  • @Herohtar actually I have padded the string with `0` so If I use `int` the padding would be gone and thus `00000010` will become `10` :( – Moeez Oct 26 '19 at 04:16
  • I am not quite understanding the problem here. Can you explain? – Gymhgy Oct 26 '19 at 04:22
  • 1
    Forget about the padding, you need to use the correct types. If you are working with `part1` and `part2` separately, you should use `byte`, because that is 8 bits (the number of characters in your example strings). At the very end, after you have done all the binary operations, *then* you can use something like `Convert.ToString(result, 2).PadLeft(8, '0')`, for example, to print the result with the correct padding. – Herohtar Oct 26 '19 at 04:24
  • @Herohtar I have to work with the whole `00000010` and the final output for `part1` would be `10000101` so I can't remove the padding – Moeez Oct 26 '19 at 04:26
  • Yes you can. The "padding" is still there, because it's a numeric type. Try it. – Herohtar Oct 26 '19 at 04:27
  • 1
    What Herohtar is saying is first you perform your operation with `byte`, then you convert the result back to a string and pad. In a numeric type, the "padding" is still there, except you cannot see it when you print it – Gymhgy Oct 26 '19 at 04:28
  • 2
    it's actually not all that clear what you're trying to do here - what's with the spit operation and upper and lower octet handling here?.. I think you mean to toggle a bit within your bit string? you're essentially just going to do an XOR operation on it by position (shift n), right? – Brett Caswell Oct 26 '19 at 04:36
  • I have tried this `byte[] bytes = Encoding.ASCII.GetBytes(c3.Substring(0, 8));` and in result I am getting can be seen on this link https://ibb.co/T4FNQRD – Moeez Oct 26 '19 at 04:38
  • @BrettCaswell yes exaclty – Moeez Oct 26 '19 at 04:39

1 Answers1

0

You may convert strings to bytes, to be able to manipulate bits, and next you convert values to strings.

So you can use this:

// Convert string of binary value (base 2) to byte
byte v1 = Convert.ToByte("00000010", 2);
byte v2 = Convert.ToByte("11110100", 2);

// Operate bits
v1 = (byte)( v1 | 0b10000000 );
v1 = (byte)( v1 | ( v2 & 0b10000000 ) >> 7 );
v2 = (byte)( v2 & ~0b10000000 );

// Convert to string formatted
string result1 = Convert.ToString(v1, 2).PadLeft(8, '0');
string result2 = Convert.ToString(v2, 2).PadLeft(8, '0');

Console.WriteLine(result1);
Console.WriteLine(result2);

Result:

10000011
01110100

It forces the MSB of part1.
It copies the MSB of part2 to LSB of part1.
It clears the MSB of part2.

If you don't use C#7, use 128 instead of 0b10000000.

As you requested, if I understood what you ask for. But you say: part1=10000101 and part2=01110100... so I don't understand what you wrote but perhaps there is a mistake and you wanted to write 10000011 instead of 10000101.

If you want to toggle bits (0=>1 and 1=>0), use:

v1 = (byte)( v1 ^ 128);
v1 = (byte)( v1 | ( v2 & 128 ) >> 7 );
v2 = (byte)( v2 ^ 128 );

It toggles the MSB of part1.
It copies the MSB of part2 to LSB of part1.
It toggles the MSB of part2.

Bitwise operators

Bitwise and shift operators (C# reference)

Boolean algebra

  • hmm... I could be mistaken here.. but I think you're doing an OR operation when the intent is do an XOR (`^`) – Brett Caswell Oct 26 '19 at 04:46
  • The OP talked about setting MSB of part1 so it is OR. But what OP want to do is more complicated and I don't really understand english... –  Oct 26 '19 at 04:50
  • hmm.. I'm not sure I understand how setting the bit in `0b10000000` makes the operation an OR against `v1` in your example or that explaination.. so let me rephrase with an observation.. `( v1 | 0b10000000 )` and `( v1 ^ 0b10000000 )` result in the same value here `0b10000010` (the same for v2), but one of those methods is correct.. you think it's OR, but I'm not sure about that.. as I'm pretty sure bit toggling uses exclusive OR (XOR) `^` here.. – Brett Caswell Oct 26 '19 at 05:02
  • right.. but the reference to set the bit was for `0b10000000`, not the toggle operation, right? – Brett Caswell Oct 26 '19 at 05:05
  • The OP could use BitConverter. For example: `byte[] bytes = BitConverter.GetBytes(value);` then set the bits: `byte byte1 = (byte)(bytes[0] & 0x7F); byte byte2 = (byte)((bytes[1] << 1) | 0x81);`. Re-assembled with, for example, `short converted = BitConverter.ToInt16(new[] { byte1, byte2 }, 0);`. Then, if a string representation is needed for the bytes or the result... – Jimi Oct 26 '19 at 05:30
  • @Faisal I think I understand what you want to do with bits. Answer updated. –  Oct 26 '19 at 06:23
  • @OlivierRogier there is no mistake and I want `10000101` for `part1` – Moeez Oct 26 '19 at 07:15
  • @Faisal So your algorithm is more complex than what you wrote. What are the rules and do you want to toggle bits or force bits? –  Oct 26 '19 at 07:22
  • @OlivierRogier I have also updated my question and added the rule – Moeez Oct 26 '19 at 07:33
  • 1
    I don't understand all the rules text. But for bits, it does not produce 10000101 but 10000011. There is an error somewhere: in the result expected or in the rule, since the result is based on modifying bit #2 and #3 and not only MSB #8 and LSB #1. –  Oct 26 '19 at 07:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201443/discussion-between-faisal-and-olivier-rogier). – Moeez Oct 26 '19 at 07:43