Node.js转C#:BigInteger校验和转Uint8Array等价实现问询
checksumToUintArray Function Let's break down how to translate your Node.js function to C# properly, starting with the original logic then filling in your partial code.
First, here's the original Node.js function for reference:
// @param {BigInteger} checksum // @returns {Uint8Array} function checksumToUintArray(checksum) { var result = new Uint8Array(8); for (var i = 0; i < 8; ++i) { result[7 - i] = checksum.and(31).toJSNumber(); checksum = checksum.shiftRight(5); } return result; }
Key Logic Breakdown
This function repeats two core steps across 8 iterations:
- Extracts the lower 5 bits of the checksum (using
& 31, since 31 equals0b11111in binary) and stores it in the result array, starting from the last index and moving backwards. - Performs a logical right shift of the checksum by 5 bits—critical because checksums are treated as unsigned values.
C# Equivalent Implementations
1. Exact Match (Using BigInteger for Full Compatibility)
Since your Node.js function uses BigInteger, the most accurate C# version leverages System.Numerics.BigInteger (you'll need to add a reference to the System.Numerics assembly). This handles large values beyond 64-bit integer ranges, just like the original:
using System.Numerics; public static byte[] ChecksumToUintArray(BigInteger checksum) { var result = new byte[8]; // `byte` matches Uint8Array's 8-bit unsigned integer type for (int i = 0; i < 8; i++) { // Extract lower 5 bits and cast to byte result[7 - i] = (byte)(checksum & 31); // Logical right shift by 5 bits (BigInteger uses logical shift for positive values) checksum = checksum >> 5; } return result; }
2. Using long Parameter (As Your Partial Code Started)
If you're certain the checksum will fit within a non-negative 64-bit integer (i.e., it won't exceed ulong.MaxValue), you can adapt your partial code. Note that we need to avoid arithmetic right shift (which would sign-extend negative values) by casting to ulong first:
public static uint[] ChecksumToUintArray(long checksum) { var result = new uint[8]; for (int i = 0; i < 8; ++i) { // Extract lower 5 bits and cast to uint result[7 - i] = (uint)(checksum & 31); // Perform logical right shift: cast to ulong to prevent sign extension checksum = (long)((ulong)checksum >> 5); } return result; }
Quick Notes
- For a perfect match with JavaScript's
Uint8Array, usebyte[]as the return type in C#—byteis an 8-bit unsigned integer, identical to the JS type. - The logical right shift fix (casting to
ulong) is essential: using plain>>on a signedlongwould fill high bits with 1 for negative values, breaking the checksum logic.
内容的提问来源于stack exchange,提问作者zig

