#javascript #c# #bit-manipulation
#javascript #c# #манипулирование битами
Вопрос:
Я пытаюсь преобразовать следующую функцию C # в Javascript, но мне не очень повезло (см. Мою попытку ниже).
Исходный код C #:
using System;
public class Program
{
const UInt16 MASK = 0xA001;
public static void Main()
{
byte[] test = System.Text.Encoding.ASCII.GetBytes("A TEST STRING");
ushort result = Program.GetChecksum(test);
}
public static ushort GetChecksum(byte[] pBytes)
{
ushort result = 0;
int vCount = pBytes.Length;
byte b;
for (int i = 0; i < vCount; i )
{
b = pBytes[i];
for (byte cnt = 1; cnt <= 8; cnt )
{
if (((b % 2) != 0) ^ ((result % 2) != 0))
{
result = (ushort)((result >> 1) ^ MASK);
}
else
{
result = (ushort)(result >> 1);
}
b = (byte)(b >> 1);
}
}
return resu<
}
}
Моя попытка преобразования:
Javascript:
const MASK = 0xA001;
const GetChecksum = (b: Buffer) => {
const result = Buffer.alloc(10).fill(0); // Don't know how much to alloc here
for (let i = 0; i < b.length; i )
{
const byte = b[i];
for (let j = 1; j <= 8; j )
{
const t1 = (byte % 2) !== 0;
const t2 = (result[i] % 2) !== 0;
result[i] = (!(t1 amp;amp; t2) amp;amp; (t1 || t2))
? ((result[i] >> 1) ^ MASK)
: (result[i] >> 1);
result[i] = byte >> 1;
}
}
return resu<
}
const x = GetChecksum(Buffer.from('THIS IS A TEST','ascii'));
console.log(x.toString('ascii'));
В частности, я не могу воспроизвести условие: (((b % 2) != 0) ^ ((result % 2) != 0))
, хотя я думаю, что в моей попытке есть несколько проблем.
Любая помощь здесь будет оценена!
Ответ №1:
Эквивалент javascript этого кода:
const MASK = 0xA001;
function getChecksum(bytes) {
let result = 0; // this is a number not a buffer
for (let b of bytes) { // for each byte in bytes (clearer than 'for' with an index 'i')
for (let ctn = 1; ctn <= 8; ctn ) { // same as C#
if (((b % 2) !== 0) ^ ((result % 2) !== 0)) { // same as C#
result = (result >> 1) ^ MASK; // same as C#
} else {
result = result >> 1; // same as C#
}
b = b >> 1; // same as C#
}
}
return resu<
};
let buffer = Buffer.from("A TEST STRING", "ascii");
let result = getChecksum(buffer);
let checksumString = result.toString(16);
console.log(checksumString);
Комментарии:
1. Разве вы не хотели
const
бы вместоlet
— и>>>
(беззнаковый сдвиг вправо) вместо>>
?2. @Dai
result
меняется для каждого байта в массиве, поэтому этого не может бытьconst
, что касается сдвига вправо без знака, я подумаю, как только выясню, что именно делает исходный код.3. Я имел в виду использование
const
forbuffer
и внешнегоresult
andchecksumString
.4. @Dai в использовании
let
для них тоже нет проблем — и сдвиг вправо без знака здесь не понадобится, потому чтоresult
, поскольку это число (намного больше, чем 16-разрядноеshort
, используемое в коде C #), достаточно велико, чтобы большинство крайних левых битов всегда0
были такими>>
и>>>
имелив этом случае результат тот же. Кроме того, текущий байтb
по умолчанию беззнаковый, поэтому>>>
здесь тоже ничего не изменится
Ответ №2:
Я надеюсь, что это даст вам ключ к разгадке:
if ((((b % 2) | 0) !== 0) ^ (((result % 2) >>> 0) !== 0)) {