Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Software computed CRC32 #95

Merged
merged 1 commit into from
Oct 9, 2024

Conversation

albyrock87
Copy link
Contributor

@albyrock87 albyrock87 commented Oct 6, 2024

Hi, apparently my iOS app is crashing in the iOS Simulator (M3 MacBook) due to a NotSupportedException thrown by LogEntry.CreateChecksum().

This PR introduces a software-computed CRC32 computation based on System.IO.Hashing code.

I didn't want to introduce a new dependency but I feel like it'd be probably better to use System.IO.Hashing due to performance reasons.

Note: I wasn't able to compile the solution, so I just hope this builds and works as expected.

Thanks for this library!

@koculu
Copy link
Owner

koculu commented Oct 6, 2024

Thank you @albyrock87 for your contribution.
"Fallback to slower CRC 32 computation rather than throwing platform not supported exception" is a nice approach.
There is a compilation failure in the MR related with language versions.
If you fix the issue, the MR looks good and can be merged.

C# Lang version can be configured in Directory.Build.props file.

@albyrock87 albyrock87 force-pushed the add-support-for-crc32-software branch from 4cdd19c to 1eec365 Compare October 9, 2024 08:32
@albyrock87 albyrock87 force-pushed the add-support-for-crc32-software branch from 1eec365 to 5985753 Compare October 9, 2024 09:30
@albyrock87
Copy link
Contributor Author

albyrock87 commented Oct 9, 2024

@koculu the PR should compile now, but I have some observations:

  • the software-computed CRC32 does NOT match any of the ones I found here and on other websites
  • even the arm64 computed CRC32 does NOT match any of them (I'm testing on a MacBook M3)
  • and the software-computed CRC32 does NOT match the arm64 computed one

Considering this is copy pasted from System.IO.Hashing, I really don't understand what's going on.

@koculu
Copy link
Owner

koculu commented Oct 9, 2024

I think we don't need to get exact same values from different CRC32 computers.

For future references I am pasting here the ChatGPT's response to your comment:

It sounds like you're encountering discrepancies between CRC32 computations across different implementations and platforms. Here are some possible reasons and steps to help you diagnose and resolve the issue:

  1. CRC32 Variants:

    • Different Polynomials: There are several variants of CRC32 that use different polynomials, such as CRC32 (IEEE), CRC32C (Castagnoli), and CRC32K (Koopman). Ensure that all implementations are using the same polynomial.
      • CRC32 (IEEE) uses polynomial 0x04C11DB7.
      • CRC32C (Castagnoli) uses 0x1EDC6F41.
    • Solution: Verify which CRC32 variant each implementation uses and align them accordingly.
  2. Initial Seed Value:

    • Initial CRC Value: Some CRC algorithms use an initial value (seed) of 0xFFFFFFFF, while others use 0x00000000.
    • Solution: Ensure that all implementations start with the same initial seed.
  3. Reflected Input and Output:

    • Bit Reflection: Some algorithms perform bitwise reflection (reversal) on input bytes and the final CRC value.
    • Solution: Check if the implementations perform input/output reflection and make sure they are consistent.
  4. Endianness Issues:

    • Byte Order: Differences in endianness between platforms (e.g., ARM64 vs. x86) can affect the computation.
    • Solution: Make sure that the data is processed in the correct byte order in all implementations.
  5. Hardware vs. Software Implementation:

    • ARM64 Hardware Acceleration: On ARM64 platforms, hardware instructions might be used for CRC computation, which could differ from software implementations.
    • Solution: Verify that both the software and hardware implementations are configured identically.
  6. Data Consistency:

    • Input Data: Even minor differences in the input data will result in different CRC values.
    • Solution: Ensure that the exact same data is being hashed in all cases.
  7. System.IO.Hashing Nuances:

    • Correct Class Usage: System.IO.Hashing provides different classes for different CRC variants.
      • Use Crc32 for CRC32 (IEEE).
      • Use Crc32C for CRC32C (Castagnoli).
    • Solution: Confirm that you're using the correct class corresponding to the desired CRC variant.
  8. Test Vectors:

    • Known Values: Use standard test vectors to verify your implementation.
      • For the input "123456789":
        • CRC32 (IEEE) should yield 0xCBF43926.
        • CRC32C (Castagnoli) should yield 0xE3069283.
    • Solution: Compute CRC values for these known inputs and compare them to expected results.
  9. Cross-Verification:

    • Online Tools and Libraries: Be cautious when comparing results with external sources; they might use different CRC variants.
    • Solution: Verify the CRC variant and settings used by these external tools.
  10. Debugging Steps:

    • Intermediate Values: If possible, log intermediate CRC values during computation to identify where the divergence occurs.
    • Comparison Between Implementations: Step through both the software and hardware implementations in a debugger.

Action Plan:

  • Identify the CRC Variant: Determine which CRC32 variant each implementation uses. This is crucial because different variants will produce different results.

  • Align Implementation Parameters: Ensure that the polynomial, initial seed, input/output reflection, and final XOR value are the same across all implementations.

  • Check Endianness: Explicitly specify byte order when processing data to avoid endianness-related issues.

  • Validate with Test Vectors: Use known inputs and expected CRC outputs to test each implementation individually.

  • Review the Code:

    • Double-check that the code copied from System.IO.Hashing is correctly integrated.
    • Ensure that any platform-specific code (e.g., ARM64 optimizations) is consistent with the software implementation.
  • Consult Documentation:

    • Review the documentation for System.IO.Hashing to understand any default settings or peculiarities.
    • Look into the documentation for ARM64 CRC instructions to see if there are any known issues or differences.

Additional Resources:

If you can share snippets of the code or specific details about the implementations, I can help you further pinpoint the issue.

@koculu koculu merged commit ac3c9b2 into koculu:main Oct 9, 2024
1 check passed
@albyrock87 albyrock87 deleted the add-support-for-crc32-software branch October 9, 2024 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants