2

I am trying to convert the following C# function into Javascript, but I haven't had much luck (see my attempt below).

Original C# code:

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 result;
    }
}

My conversion attempt:

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 && t2) && (t1 || t2))
            ? ((result[i] >> 1) ^ MASK) 
            : (result[i] >> 1);

          result[i] = byte >> 1;
        }
    }
    return result;
}

const x =  GetChecksum(Buffer.from('THIS IS A TEST','ascii'));
console.log(x.toString('ascii'));

In particular, I'm not able to replicate the condition: (((b % 2) != 0) ^ ((result % 2) != 0)), although I think there are multiple issues in my attempt.

Any help here would be appreciated!

2 Answers 2

2

The javascript equivalent of that code is:

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 result;
};

let buffer = Buffer.from("A TEST STRING", "ascii");
let result = getChecksum(buffer);
let checksumString = result.toString(16);

console.log(checksumString);
Sign up to request clarification or add additional context in comments.

4 Comments

Wouldn't you want const instead of let - and >>> (unsigned right-shift) instead of >>?
@Dai result is changing for each byte in the array so it can't be const, as for the unsigned right-shift, I'll think about once I figure out what the original code is doing exactly.
I meant using const for buffer and the outer result and checksumString.
@Dai there is no problem in using let for those too - and the unsigned right-shift won't be needed here because result, since it is a number (way larger than the 16-bit short used in the C# code), is big enough that most of the leftmost bits are always 0 so >> and >>> have the same results in this case. Also, the current byte b is unsigned by default so >>> won't make a difference there too
-1

I hope this gives you a clue:

if ((((b % 2) | 0) !== 0) ^ (((result % 2) >>> 0) !== 0)) {

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.