You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现给定单字节浮点数解包函数的逆向打包功能?

Reverse Engineering the unpack Function: Implementing pack

First, let's break down how your original unpack function maps a byte to a double, then reverse each step to build the inverse function.

Step 1: Break Down the Original unpack Logic

Let's restate the core behavior clearly to make reversal easier:
Given a byte count, the function first computes xor = count ^ 0xFF, then branches into three cases:

  • If xor == 0x08: returns 0.0
  • If the lower 3 bits of xor (called exponent) are 0: returns xor / 512.0
  • Otherwise: combines the upper 5 bits of xor (called mantissa) with a leading 1 bit, shifts left by exponent-1, then divides by 512 to get the final double.

Since count = xor ^ 0xFF, our goal is to find the correct xor value for a given double, then compute count from it.

Step 2: Define the Inverse pack Logic

We'll mirror the three cases from unpack to cover all valid inputs:

Case 1: Input is 0.0

From unpack, we know 0.0 maps directly to xor = 0x08. So:
count = 0x08 ^ 0xFF = 0xF7

Case 2: Input fits the "exponent 0" range

In unpack, this case returns xor / 512.0 where:

  • xor is an integer between 0-255
  • The lower 3 bits of xor are 0 (so xor is a multiple of 8)
  • xor != 0x08 (already handled in Case 1)

For a given double v, calculate xor_candidate = v * 512. To be valid:

  • xor_candidate must be a whole number within 0-255
  • xor_candidate % 8 == 0
  • xor_candidate != 0x08

If all checks pass, count = xor_candidate ^ 0xFF

Case 3: Input fits the "non-zero exponent" range

The original formula here is:
v = ((mantissa | 0x100) << (exponent - 1)) / 512.0
Where:

  • mantissa = xor & 0xF8 (upper 5 bits of xor, multiples of 8)
  • exponent = xor & 0x07 (values 1-7, since exponent 0 is Case 2)

Rewriting to solve for components:
Multiply both sides by 1024 (2^10) to simplify:
v * 1024 = (0x100 | mantissa) * (2 ^ exponent)

0x100 | mantissa is a 9-bit number ranging from 0x100 (256) to 0x1F8 (504), in steps of 8. For a given v, loop through exponents 1-7 to find one where:
(v * 1024) / (2^exponent) is an integer between 256-504, and divisible by 8.

Once found:

  • mantissa = combined_value - 0x100
  • xor = mantissa | exponent
  • count = xor ^ 0xFF

Step 3: Implement the pack Function

Here's the C# implementation matching your original code's language:

private byte pack(double value)
{
    // Case 1: Handle 0.0 directly
    if (Math.Abs(value) < 1e-9) // Account for floating point precision
    {
        return (byte)(0x08 ^ 0xFF); // Returns 0xF7
    }

    // Case 2: Check if value fits the exponent 0 range
    double xorCandidateDouble = value * 512.0;
    if (xorCandidateDouble >= 0 && xorCandidateDouble <= 255)
    {
        int roundedCandidate = (int)Math.Round(xorCandidateDouble);
        // Check if the value is nearly an integer, meets divisibility, and isn't 0x08
        if (Math.Abs(xorCandidateDouble - roundedCandidate) < 1e-9 
            && (roundedCandidate & 0x07) == 0 
            && roundedCandidate != 0x08)
        {
            return (byte)(roundedCandidate ^ 0xFF);
        }
    }

    // Case 3: Find valid exponent and mantissa for non-zero exponent range
    for (int exponent = 1; exponent <= 7; exponent++)
    {
        double combinedDouble = value * 1024.0 / Math.Pow(2, exponent);
        if (combinedDouble >= 256 && combinedDouble <= 504)
        {
            int combined = (int)Math.Round(combinedDouble);
            if (Math.Abs(combinedDouble - combined) < 1e-9 && combined % 8 == 0)
            {
                byte mantissa = (byte)(combined - 0x100);
                byte xor = (byte)(mantissa | exponent);
                return (byte)(xor ^ 0xFF);
            }
        }
    }

    // Throw error if no valid mapping exists (adjust to return default if needed)
    throw new ArgumentOutOfRangeException(nameof(value), "Input double has no valid corresponding byte from the original unpack function.");
}

Key Notes

  • Floating Point Precision: We use a small epsilon (1e-9) to compare values, since doubles can't represent all decimal values exactly.
  • Error Handling: The function throws an exception for inputs that don't map to any valid byte from unpack—you can adjust this to return a default byte if your use case requires it.
  • Validation: Each case includes checks to ensure the input fits the valid ranges of the original unpack function.

内容的提问来源于stack exchange,提问作者user1930728

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:45:36