如何在 C# 中操作二进制字符串的位

Posted

技术标签:

【中文标题】如何在 C# 中操作二进制字符串的位【英文标题】:How to manipulate bits of a binary string in C# 【发布时间】:2020-02-22 08:44:40 【问题描述】:

我正在处理c# desktop application。我有一个字符串,我想toggle 它。

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

将上面的字符串一分为二(子字符串)

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

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

对于part1,第一个八位字节的 MSB 应设置为 1,对于 part2,因此该位应移入第一个八位字节的 LSB,第二个(最后一个)八位字节的 MSB 应设置为 0 ,因此该位应移入第一个八位字节的 LSB。这给出了二进制 part1 = 10000101part2 = 01110100

我已经检查了这个解决方案Binary array after M range toggle operations,但仍然无法理解。

规则

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.

如何使用二进制字符串执行此切换?

任何帮助将不胜感激

【问题讨论】:

如果你想做二进制操作,你不应该使用string。使用byteint 或其他一些适当的数字类型。仅在需要显示输出时才转换为字符串。 @Herohtar 实际上我已经用0 填充了字符串,所以如果我使用int,填充将消失,因此00000010 将变为10 :( 忘记填充,您需要使用正确的类型。如果您分别使用part1part2,则应使用byte,因为那是8 位(示例字符串中的字符数)。最后,在您完成所有二进制操作后,然后您可以使用 Convert.ToString(result, 2).PadLeft(8, '0') 之类的东西,例如,打印带有正确填充的结果。 Herohtar 的意思是首先您使用byte 执行操作,然后将结果转换回字符串和填充。在数字类型中,“填充”仍然存在,只是打印时看不到它 实际上并不是很清楚您要在这里做什么-这里的吐水操作和上下八位字节处理是什么?..我认为您的意思是在位字符串中进行一些切换?您实际上只是要按位置(移位 n)对其进行 XOR 操作,对吗? 【参考方案1】:

您可以将字符串转换为字节,以便能够操作位,然后将值转换为字符串。

所以你可以使用这个:

// 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);

结果:

10000011
01110100

它强制第 1 部分的 MSB。 它将part2的MSB复制到part1的LSB。 它清除part2的MSB。

如果您不使用 C#7,请使用 128 而不是 0b10000000

如您所愿,如果我理解您的要求。但你说:part1=10000101 和 part2=01110100...所以我不明白你写了什么,但也许有一个错误,你想写 10000011 而不是 10000101

如果要切换位(0=>1 和 1=>0),请使用:

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

它切换第 1 部分的 MSB。 它将part2的MSB复制到part1的LSB。 它切换第 2 部分的 MSB。

Bitwise operators

Bitwise and shift operators (C# reference)

Boolean algebra

【讨论】:

hmm...我在这里可能弄错了..但我认为您正在执行 OR 操作,而意图是执行 XOR (^) OP 谈到设置 part1 的 MSB 所以它是 OR。但是OP想要做的更复杂,我不太懂英语...... hmm.. 我不确定我是否理解在您的示例或说明中设置0b10000000 中的位如何使操作成为针对v1 的 OR .. 所以让我换个说法..( v1 | 0b10000000 )( v1 ^ 0b10000000 ) 在这里得到相同的值0b10000010(v2 相同),但其中一种方法是正确的.. 你认为它是 OR,但我不确定。我很确定位切换在这里使用异或(XOR)^.. 对.. 但是设置位的引用是针对0b10000000,而不是切换操作,对吧? 我不明白所有的规则文本。但是对于位,它不会产生 10000101 而是 10000011。某处存在错误:在预期的结果或规则中,因为结果是基于修改位 #2 和 #3 而不仅仅是 MSB #8 和 LSB #1 .

以上是关于如何在 C# 中操作二进制字符串的位的主要内容,如果未能解决你的问题,请参考以下文章

位运算

c#中的位运算

如何优雅地使用Redis之位图操作

如何优雅地使用Redis之位图操作

JAVA中的位运算和使用举例

HashMap中的位运算