2017-01-09 4 views
4

Я пытаюсь перестроить конструкцию устройства последовательного порта, использующего hdlc для его формата пакета. Основанный на документации пакет должен содержать побитовое инвертирование команды (первые 4 байта), которая в этом кейс есть "HELO". Мониторинг последовательного порта при использовании оригинальной программы показывает, что побитовая инверсия должна быть:Вычисление побитовой инверсии char

HELO -> b7 ba b3 b0 
READ -> ad ba be bb 

Проблема заключается в том, что я не получаю значение даже отдаленно близко.

public object checksum 
    { 

     get 
     { 
      var cmdDec = (int)Char.GetNumericValue((char)this.cmd); 
      return (cmdDec^0xffffffff); 
     } 
    } 
+1

Что такое 'this.cmd', пожалуйста? 'String',' byte [] ',' char [] ', что-то еще? –

+0

this.cmd = HELO – user1698144

+0

'0xFFFFFFFF' не является литералом' int'. Это либо 'uint', либо' long', в зависимости от контекста (в данном случае это 'long'). Таким образом, результат 'int', являющийся XOR'd с' long', вернет 'long'. Кроме того, если вы выполняете побитовое инвертирование, вы можете использовать оператор '~'. – Abion47

ответ

2

You должны работать с байтами, а не с chars:

string source = "HELO"; 

// Encoding.ASCII: I assume that the command line has ASCII encoded commands only 
byte[] result = Encoding.ASCII 
    .GetBytes(source) 
    .Select(b => unchecked((byte)~b)) // unchecked: ~b returns int; can exceed byte.MaxValue 
    .ToArray(); 

Test (давайте представлять result как шестнадцатеричные)

// b7 ba b3 b0 
Console.Write(string.Join(" ", result.Select(b => b.ToString("x2")))); 
1

Char не байт. Вы должны использовать байты вместо символов.


So this.cmd - это массив байтов? Вы можете использовать BitConverter.ToUInt32()

Псевдо: (вы можете исправить некоторые отливку)

public uint checksum 
{ 
    get 
    { 
     var cmdDec = BitConverter.ToUInt32(this.cmd, 0); 
     return (cmdDec^0xffffffff); 
    } 
} 

если this.cmd является строка, которую вы могли бы получить байтовый массив из него с Encoding.UTF8.GetBytes(string)

0

Вашей побитовая инверсия не делать то, что вы думаете, что он делает. Возьмем, например, следующее:

int i = 5; 

var j = i^0xFFFFFFFF; 
var k = ~i; 

Первый пример выполнения инверсии, как вы делаете это, по XOR-ное количество с максимальным значением. Второе значение использует оператор C# Bitwise-NOT ~.

После выполнения этого кода, j будет long значение, равное 4294967290, в то время как k будет int значение, равное -6. Их двоичное представление будет таким же, но j будет включать в себя еще 32 бита 0, чтобы идти вместе с ним. Существует также очевидная проблема, заключающаяся в том, что они являются совершенно разными числами, поэтому любая математика, выполненная над значениями, будет полностью различной в зависимости от того, что вы используете.

Смежные вопросы