在C#中从二进制哈希解析4位代码的问题排查
Hey there, let's break down where things might be going wrong with your SHA512 hash processing step by step. First, let's restate the core requirement to make sure we're on the same page:
Core Requirement: Extract the first 6 bits and last 7 bits from a SHA512 hash's raw binary bit stream, concatenate them into a 13-bit binary number, then convert it to a 4-digit decimal number (range 0000-8192, pad with leading zeros if needed). For your test case, the expected output is 5138.
1. First, Check if Your Hash Calculation is Producing the Correct Raw Binary
You tried three hash calculation methods, but you need to ensure all three output the exact same 512-bit raw byte array—if they don't, everything downstream will fail. Here are common pitfalls in each method:
- String → UTF8 byte array: Double-check that your input string is encoded with standard UTF-8 (no BOM markers, no accidental GBK/UTF-16 conversion). Even a single wrong byte will throw off the entire hash.
- Base64 string → byte array: Make sure you're using a proper Base64 decoder that handles standard Base64 (not URL-safe variants unless your input uses them). Extra newlines or whitespace in the Base64 input will also break decoding.
- String → binary string: This is the riskiest method if done wrong. You shouldn't convert each character of the input string directly to binary—instead, first convert the input string to a UTF8 byte array, then convert each byte to an 8-bit binary string (padding with leading zeros to make it 8 bits), then concatenate all those to get a 512-bit continuous binary stream.
2. Fixes for Your Bit Extraction Methods
Both of your extraction approaches are likely failing due to misaligned bit positioning or incorrect handling of the binary stream:
Issue with Bitwise Operations
When using bitwise operations on the raw byte array:
- First 6 bits: These are the top 6 bits of the first byte (index 0) of the SHA512 hash. For example, if the first byte is
0b10110011, the first 6 bits are101100(shift right by 2 bits to drop the last 2 bits). - Last 7 bits: These are the bottom 7 bits of the last byte (index 63) of the hash. For example, if the last byte is
0b10110011, the last 7 bits are0110011(mask with0x7Fto clear the top bit). - Critical note: Ensure you're counting bits from the most significant bit (MSB) first—this is the standard for hash bit streams.
Issue with Binary String Slicing
If you're converting the raw hash to a 512-bit binary string:
- Always pad each byte to 8 bits: When converting a byte to binary, don't just output its raw binary (e.g.,
0x05shouldn't become101—it needs to be00000101). If you skip padding, your binary string will be shorter than 512 bits, and your slicing will grab the wrong bits. - Slice correctly: The first 6 bits are the first 6 characters of the 512-bit string, and the last 7 bits are the final 7 characters. Double-check that your binary string is exactly 512 characters long before slicing.
3. Reverse-Validate with Your Expected Output
To confirm your flow, reverse-engineer the expected 5138:
- 5138 in binary is
1010000100010(13 bits) - Split this into first 6 bits:
101000, last 7 bits:0100010 - When you generate your SHA512 hash, verify that its raw binary stream starts with
101000and ends with0100010. If it doesn't, your hash input is wrong, or your extraction logic is off.
4. Most Common Misstep to Avoid
The #1 mistake here is confusing the hexadecimal hash string (the 128-character string you often see) with the raw binary hash. You can't slice the hex string to get bits—each hex character represents 4 bits, so slicing 6 hex characters would give you 24 bits, not the 6 bits you need. Always work with the raw 512-bit byte array or its properly padded binary string equivalent.
内容的提问来源于stack exchange,提问作者Karlito

