11 Commits

Author SHA1 Message Date
Matt Nadareski
a334ffc25a Slightly more cleanup and clarification 2026-01-27 09:13:30 -05:00
Matt Nadareski
3211f1a218 Use new null checking syntax 2026-01-25 17:12:44 -05:00
Matt Nadareski
3c451b8570 Add editorconfig, fix issues 2026-01-25 17:11:44 -05:00
Matt Nadareski
ecd52b1a0e Add issue templates 2026-01-11 09:25:38 -05:00
Matt Nadareski
0075b9b1ad Add CRC-32/DVD-ROM-EDC (fixes #4) 2026-01-11 09:20:15 -05:00
Matt Nadareski
214b449e5e Format GHA definitions 2025-11-17 08:38:13 -05:00
Matt Nadareski
0bb3e541be Fix one property group 2025-11-13 20:38:04 -05:00
Matt Nadareski
d91220a2e4 Bump version 2025-11-13 07:25:14 -05:00
Matt Nadareski
e60a1fbe3c These can be static 2025-11-12 21:41:40 -05:00
Matt Nadareski
978a3847de Add support for .NET 10 2025-11-12 20:00:11 -05:00
Matt Nadareski
48da4cd88e Update rolling tag 2025-10-26 20:21:42 -04:00
48 changed files with 512 additions and 203 deletions

167
.editorconfig Normal file
View File

@@ -0,0 +1,167 @@
# top-most EditorConfig file
root = true
# C# files
[*.cs]
# Indentation and spacing
charset = utf-8
indent_size = 4
indent_style = space
tab_width = 4
trim_trailing_whitespace = true
# New line preferences
end_of_line = lf
insert_final_newline = true
max_line_length = unset
# using directive preferences
csharp_using_directive_placement = outside_namespace
dotnet_diagnostic.IDE0005.severity = error
# Code-block preferences
csharp_style_namespace_declarations = block_scoped
csharp_style_prefer_method_group_conversion = true
csharp_style_prefer_top_level_statements = false
# Expression-level preferences
csharp_prefer_simple_default_expression = true
csharp_style_inlined_variable_declaration = true
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable
dotnet_diagnostic.IDE0001.severity = warning
dotnet_diagnostic.IDE0002.severity = warning
dotnet_diagnostic.IDE0004.severity = warning
dotnet_diagnostic.IDE0010.severity = error
dotnet_diagnostic.IDE0051.severity = warning
dotnet_diagnostic.IDE0052.severity = warning
dotnet_diagnostic.IDE0072.severity = warning
dotnet_diagnostic.IDE0080.severity = warning
dotnet_diagnostic.IDE0100.severity = error
dotnet_diagnostic.IDE0110.severity = error
dotnet_diagnostic.IDE0120.severity = warning
dotnet_diagnostic.IDE0121.severity = warning
dotnet_diagnostic.IDE0240.severity = error
dotnet_diagnostic.IDE0241.severity = error
dotnet_style_coalesce_expression = true
dotnet_style_namespace_match_folder = false
dotnet_style_null_propagation = true
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_collection_expression = when_types_loosely_match
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_compound_assignment = true
csharp_style_prefer_simple_property_accessors = true
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_prefer_simplified_boolean_expressions = true
csharp_style_prefer_unbound_generic_type_in_nameof = true
# Field preferences
dotnet_diagnostic.IDE0044.severity = warning
dotnet_style_readonly_field = true
# Language keyword vs. framework types preferences
dotnet_diagnostic.IDE0049.severity = error
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# Modifier preferences
csharp_prefer_static_local_function = true
csharp_style_prefer_readonly_struct = true
dotnet_diagnostic.IDE0036.severity = warning
dotnet_diagnostic.IDE0040.severity = error
dotnet_diagnostic.IDE0380.severity = error
dotnet_style_require_accessibility_modifiers = always
# New-line preferences
dotnet_diagnostic.IDE2000.severity = warning
dotnet_diagnostic.IDE2002.severity = warning
dotnet_diagnostic.IDE2003.severity = warning
dotnet_diagnostic.IDE2004.severity = warning
dotnet_diagnostic.IDE2005.severity = warning
dotnet_diagnostic.IDE2006.severity = warning
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
dotnet_style_allow_multiple_blank_lines_experimental = false
dotnet_style_allow_statement_immediately_after_block_experimental = false
# Null-checking preferences
csharp_style_conditional_delegate_call = true
# Parameter preferences
dotnet_code_quality_unused_parameters = all
dotnet_diagnostic.IDE0280.severity = error
# Parentheses preferences
dotnet_diagnostic.IDE0047.severity = warning
dotnet_diagnostic.IDE0048.severity = warning
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_operators = always_for_clarity
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
# Pattern-matching preferences
dotnet_diagnostic.IDE0019.severity = warning
dotnet_diagnostic.IDE0020.severity = warning
dotnet_diagnostic.IDE0038.severity = warning
dotnet_diagnostic.IDE0066.severity = none
dotnet_diagnostic.IDE0083.severity = warning
dotnet_diagnostic.IDE0260.severity = warning
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
# this. and Me. preferences
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# var preferences
csharp_style_var_for_built_in_types = false
csharp_style_var_when_type_is_apparent = true
# .NET formatting options
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true
# C# formatting options
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = false
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false

View File

@@ -0,0 +1,27 @@
---
name: Feature Request
about: For when you know better than me what you want
title: "[Request]"
labels: enhancement
assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://github.com/SabreTools/SabreTools.Hashing/releases/tag/rolling) to see if the feature already exists.
- Check [previous issues](https://github.com/SabreTools/SabreTools.Hashing/issues) to see if any of those are related to what you're about to ask for.
If none of those apply, then continue...
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

21
.github/ISSUE_TEMPLATE/informational.md vendored Normal file
View File

@@ -0,0 +1,21 @@
---
name: Info
about: Something you need to tell me
title: "[Info]"
labels: question
assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://github.com/SabreTools/SabreTools.Hashing/releases/tag/rolling) to see if the feature already exists.
- Check [previous issues](https://github.com/SabreTools/SabreTools.Hashing/issues) to see if any of those are related to what you're about to ask for.
If none of those apply, then continue...
**Is your information related to one of the checksums/hashes supported or something that isn't a bug in the code? Please describe.**
A clear and concise description of what the information is. Ex. With the latest build of Hasher, it [...]
**Additional context**
Add any other context or screenshots about the information here.

45
.github/ISSUE_TEMPLATE/issue-report.md vendored Normal file
View File

@@ -0,0 +1,45 @@
---
name: Issue Report
about: Tell me what's wrong, seriously
title: "[Problem]"
labels: bug
assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://github.com/SabreTools/SabreTools.Hashing/releases/tag/rolling) to see if the issue has already been addressed.
- Check multiple inputs to help narrow down the issue
If all of those fail, then continue...
**Version**
What version are you using?
- [ ] Stable release (version here)
- [ ] WIP release (version here)
**Build**
What runtime version are you using?
- [ ] .NET 10 running on (Operating System)
**Describe the issue**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Create the '...' hasher
2. Run the hasher with '....'
3. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@@ -1,40 +1,48 @@
name: Build and Test
on:
push:
branches: [ "main" ]
push:
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh -d
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg,*.zip"
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh -d
- name: Update rolling tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -f rolling
git push origin :refs/tags/rolling || true
git push origin rolling --force
- name: Upload to rolling
uses: ncipollo/release-action@v1.20.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg,*.zip"
body: "Last built commit: ${{ github.sha }}"
name: "Rolling Release"
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

View File

@@ -3,21 +3,21 @@ name: Build PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
- name: Build
run: dotnet build
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Run tests
run: dotnet test
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Build
run: dotnet build
- name: Run tests
run: dotnet test

2
.vscode/launch.json vendored
View File

@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Hasher/bin/Debug/net9.0/Hasher.dll",
"program": "${workspaceFolder}/Hasher/bin/Debug/net10.0/Hasher.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console

View File

@@ -83,7 +83,7 @@ namespace Hasher.Features
foreach (string typeString in types)
{
HashType? hashType = typeString.GetHashType();
if (hashType != null && !hashTypes.Contains(hashType.Value))
if (hashType is not null && !hashTypes.Contains(hashType.Value))
hashTypes.Add(item: hashType.Value);
}
}
@@ -141,7 +141,7 @@ namespace Hasher.Features
{
// Get all file hashes for flexibility
var hashes = HashTool.GetFileHashes(file);
if (hashes == null)
if (hashes is null)
{
if (debug) Console.WriteLine($"Hashes for {file} could not be retrieved");
return;
@@ -152,7 +152,7 @@ namespace Hasher.Features
foreach (HashType hashType in hashTypes)
{
// TODO: Make helper to pretty-print hash type names
if (hashes.TryGetValue(hashType, out string? hash) && hash != null)
if (hashes.TryGetValue(hashType, out string? hash) && hash is not null)
builder.AppendLine($"{hashType}: {hash}");
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
@@ -10,7 +10,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.5.1</Version>
<Version>1.6.0</Version>
</PropertyGroup>
<!-- Support All Frameworks -->
@@ -20,18 +20,18 @@
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`)) OR $(TargetFramework.StartsWith(`net10`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Hashing\SabreTools.Hashing.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.3.2]" />
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
</ItemGroup>
</Project>

View File

@@ -15,7 +15,7 @@ namespace Hasher
var commandSet = CreateCommands(mainFeature);
// If we have no args, show the help and quit
if (args == null || args.Length == 0)
if (args is null || args.Length == 0)
{
commandSet.OutputAllHelp();
return;

View File

@@ -58,4 +58,4 @@ namespace SabreTools.Hashing.Test
}
}
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using Xunit;
@@ -16,15 +15,15 @@ namespace SabreTools.Hashing.Test
/// <summary>
/// Get an array of all hash types
/// </summary>
public static List<object[]> AllHashTypes
public static TheoryData<HashType> AllHashTypes
{
get
{
var values = Enum.GetValues(typeof(HashType));
var set = new List<object[]>();
var values = Enum.GetValues<HashType>();
var set = new TheoryData<HashType>();
foreach (var value in values)
{
set.Add([value]);
set.Add(value);
}
return set;
@@ -126,4 +125,4 @@ namespace SabreTools.Hashing.Test
TestHelper.ValidateHashes(hashDict);
}
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
@@ -24,10 +24,9 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View File

@@ -42,4 +42,4 @@ namespace SabreTools.Hashing.Test
Assert.Equal(expected, result);
}
}
}
}

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Hashing.Test
/// <summary>
/// Helper class for tests
/// </summary>
/// CRC values confirmed with <see href="https://emn178.github.io/online-tools/crc/"/>
/// CRC values confirmed with <see href="https://emn178.github.io/online-tools/crc/"/>
internal static class TestHelper
{
#region Known File Information
@@ -143,6 +143,7 @@ namespace SabreTools.Hashing.Test
{HashType.CRC32_BZIP2, "18aa4603"},
{HashType.CRC32_CDROMEDC, "b8ced467"},
{HashType.CRC32_CKSUM, "f27b3c27"},
{HashType.CRC32_DVDROMEDC, "b538afc0"},
{HashType.CRC32_ISCSI, "544d37db"},
{HashType.CRC32_ISOHDLC, "ba02a660"},
{HashType.CRC32_JAMCRC, "45fd599f"},
@@ -244,4 +245,4 @@ namespace SabreTools.Hashing.Test
public static void ValidateSize(long fileSize)
=> Assert.Equal(_hashFileSize, fileSize);
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
@@ -10,15 +9,15 @@ namespace SabreTools.Hashing.Test
/// <summary>
/// Get an array of all hash types
/// </summary>
public static List<object[]> AllHashTypes
public static TheoryData<HashType> AllHashTypes
{
get
{
var values = Enum.GetValues(typeof(HashType));
var set = new List<object[]>();
var values = Enum.GetValues<HashType>();
var set = new TheoryData<HashType>();
foreach (var value in values)
{
set.Add([value]);
set.Add(value);
}
return set;
@@ -46,4 +45,4 @@ namespace SabreTools.Hashing.Test
Assert.Equal(expected, actual);
}
}
}
}

View File

@@ -3,7 +3,7 @@ using static SabreTools.Hashing.Checksum.Constants;
namespace SabreTools.Hashing.Checksum
{
/// <see href="https://github.com/madler/zlib/blob/v1.2.11/adler32.c"/>
/// <see href="https://github.com/madler/zlib/blob/v1.2.11/adler32.c"/>
public class Adler32 : ChecksumBase<uint>
{
/// <inheritdoc/>

View File

@@ -204,17 +204,17 @@ namespace SabreTools.Hashing.Checksum
while (offset < end)
{
ulong low = local ^ (uint)(
(data[offset + 0])
data[offset + 0]
+ (data[offset + 1] << 8)
+ (data[offset + 2] << 16)
+ (data[offset + 3] << 24));
offset += 4;
local = _table[3, (byte)(low)]
local = _table[3, (byte)low]
^ _table[2, (byte)(low >> 8)]
^ _table[1, (byte)(low >> 16)]
^ _table[0, (byte)(low >> 24)]
^ local >> 32;
^ (local >> 32);
}
}
@@ -246,26 +246,26 @@ namespace SabreTools.Hashing.Checksum
while (offset < end)
{
ulong low = local ^ (uint)(
(data[offset + 0])
data[offset + 0]
+ (data[offset + 1] << 8)
+ (data[offset + 2] << 16)
+ (data[offset + 3] << 24));
ulong high = (uint)(
(data[offset + 4])
data[offset + 4]
+ (data[offset + 5] << 8)
+ (data[offset + 6] << 16)
+ (data[offset + 7] << 24));
offset += 8;
local = _table[7, (byte)(low)]
local = _table[7, (byte)low]
^ _table[6, (byte)(low >> 8)]
^ _table[5, (byte)(low >> 16)]
^ _table[4, (byte)(low >> 24)]
^ _table[3, (byte)(high)]
^ _table[3, (byte)high]
^ _table[2, (byte)(high >> 8)]
^ _table[1, (byte)(high >> 16)]
^ _table[0, (byte)(high >> 24)]
^ local >> 32;
^ (local >> 32);
}
}
@@ -297,26 +297,26 @@ namespace SabreTools.Hashing.Checksum
while (offset < end)
{
ulong low = local ^ (uint)(
(data[offset + 3])
data[offset + 3]
+ (data[offset + 2] << 8)
+ (data[offset + 1] << 16)
+ (data[offset + 0] << 24));
ulong high = (uint)(
(data[offset + 7])
data[offset + 7]
+ (data[offset + 6] << 8)
+ (data[offset + 5] << 16)
+ (data[offset + 4] << 24));
offset += 8;
local = _table[4, (byte)(low)]
local = _table[4, (byte)low]
^ _table[5, (byte)(low >> 8)]
^ _table[6, (byte)(low >> 16)]
^ _table[7, (byte)(low >> 24)]
^ _table[0, (byte)(high)]
^ _table[0, (byte)high]
^ _table[1, (byte)(high >> 8)]
^ _table[2, (byte)(high >> 16)]
^ _table[3, (byte)(high >> 24)]
^ local << 32;
^ (local << 32);
}
}

View File

@@ -1,6 +1,6 @@
namespace SabreTools.Hashing.Checksum
{
/// <see href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Optimizations"/>
/// <see href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Optimizations"/>
public class Fletcher16 : ChecksumBase<ushort>
{
/// <inheritdoc/>

View File

@@ -2,7 +2,7 @@ using static SabreTools.Hashing.Checksum.Constants;
namespace SabreTools.Hashing.Checksum
{
/// <see href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Optimizations"/>
/// <see href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Optimizations"/>
/// <remarks>Uses an Adler-32-like implementation instead of the above</remarks>
public class Fletcher32 : ChecksumBase<uint>
{
@@ -32,7 +32,7 @@ namespace SabreTools.Hashing.Checksum
if (c1 >= F32BASE)
c1 -= F32BASE;
_hash = (uint)((c1 << 16) | c0);
_hash = (c1 << 16) | c0;
return;
}
@@ -50,7 +50,7 @@ namespace SabreTools.Hashing.Checksum
// Only added so many BASE's
c1 %= F32BASE;
_hash = (uint)((c1 << 16) | c0);
_hash = (c1 << 16) | c0;
return;
}

View File

@@ -2,7 +2,7 @@ using System;
namespace SabreTools.Hashing.Checksum
{
/// <see href="https://github.com/ocornut/meka/blob/master/meka/srcs/checksum.cpp"/>
/// <see href="https://github.com/ocornut/meka/blob/master/meka/srcs/checksum.cpp"/>
public class MekaCrc : ChecksumBase<ulong>
{
/// <inheritdoc/>
@@ -43,4 +43,4 @@ namespace SabreTools.Hashing.Checksum
_hash = BitConverter.ToUInt64(temp, 0);
}
}
}
}

View File

@@ -1481,6 +1481,20 @@ namespace SabreTools.Hashing.Checksum
XorOut = 0xffffffff,
};
/// <summary>
/// CRC-32/DVD-ROM-EDC
/// </summary>
public static readonly CrcDefinition CRC32_DVDROMEDC = new()
{
Name = "CRC-32/DVD-ROM-EDC",
Width = 32,
Poly = 0x80000011,
Init = 0x00000000,
ReflectIn = false,
ReflectOut = false,
XorOut = 0x00000000,
};
/// <summary>
/// CRC-32/ISCSI
/// </summary>

View File

@@ -10,7 +10,7 @@ namespace SabreTools.Hashing.CryptographicHash
protected long _totalBytes;
/// <summary>
/// Internal byte buffer to accumulate before <see cref="_block"/>
/// Internal byte buffer to accumulate before <see cref="_block"/>
/// </summary>
protected readonly byte[] _buffer = new byte[64];

View File

@@ -132,7 +132,7 @@ namespace SabreTools.Hashing.CryptographicHash
/// The official specification for RIPEMD-128 includes tables
/// and instructions that represent a loop. Most standard implementations
/// use the unrolled version of that loop to make it more efficient.
///
///
/// The below code started with the looped version but has been converted
/// to the more standard implementation instead.
/// </remarks>

View File

@@ -133,7 +133,7 @@ namespace SabreTools.Hashing.CryptographicHash
/// The official specification for RIPEMD-160 includes tables
/// and instructions that represent a loop. Most standard implementations
/// use the unrolled version of that loop to make it more efficient.
///
///
/// The below code started with the looped version but has been converted
/// to the more standard implementation instead.
/// </remarks>

View File

@@ -136,7 +136,7 @@ namespace SabreTools.Hashing.CryptographicHash
/// The official specification for RIPEMD-128 includes tables
/// and instructions that represent a loop. Most standard implementations
/// use the unrolled version of that loop to make it more efficient.
///
///
/// The below code started with the looped version but has been converted
/// to the more standard implementation instead.
/// </remarks>

View File

@@ -138,7 +138,7 @@ namespace SabreTools.Hashing.CryptographicHash
/// The official specification for RIPEMD-160 includes tables
/// and instructions that represent a loop. Most standard implementations
/// use the unrolled version of that loop to make it more efficient.
///
///
/// The below code started with the looped version but has been converted
/// to the more standard implementation instead.
/// </remarks>

View File

@@ -138,6 +138,7 @@ namespace SabreTools.Hashing
HashType.CRC32_BZIP2 => "BZIP2",
HashType.CRC32_CDROMEDC => "CRC-32/CD-ROM-EDC",
HashType.CRC32_CKSUM => "CRC-32/CKSUM",
HashType.CRC32_DVDROMEDC => "CRC-32/DVD-ROM-EDC",
HashType.CRC32_ISCSI => "CRC-32/ISCSI",
HashType.CRC32_ISOHDLC => "CRC-32/ISO-HDLC",
HashType.CRC32_JAMCRC => "CRC-32/JAMCRC",
@@ -364,6 +365,7 @@ namespace SabreTools.Hashing
"crc32_bzip2" => HashType.CRC32_BZIP2,
"crc32_cdromedc" => HashType.CRC32_CDROMEDC,
"crc32_cksum" => HashType.CRC32_CKSUM,
"crc32_dvdromedc" => HashType.CRC32_DVDROMEDC,
"crc32_iscsi" => HashType.CRC32_ISCSI,
"crc32_isohdlc" => HashType.CRC32_ISOHDLC,
"crc32_jamcrc" => HashType.CRC32_JAMCRC,
@@ -442,4 +444,4 @@ namespace SabreTools.Hashing
};
}
}
}
}

View File

@@ -15,7 +15,7 @@ namespace SabreTools.Hashing
public static string? ByteArrayToString(byte[]? bytes)
{
// If we get null in, we send null out
if (bytes == null)
if (bytes is null)
return null;
try
@@ -38,7 +38,7 @@ namespace SabreTools.Hashing
public static ulong BytesToUInt64(byte[]? bytes)
{
// If we get null in, we send 0 out
if (bytes == null)
if (bytes is null)
return default;
ulong result = 0;
@@ -60,9 +60,9 @@ namespace SabreTools.Hashing
public static uint ReadBE32(byte[] data, int offset)
{
return (uint)(data[offset + 3]
| data[offset + 2] << 8
| data[offset + 1] << 16
| data[offset + 0] << 24);
| (data[offset + 2] << 8)
| (data[offset + 1] << 16)
| (data[offset + 0] << 24));
}
/// <summary>
@@ -71,13 +71,13 @@ namespace SabreTools.Hashing
public static ulong ReadBE64(byte[] data, int offset)
{
return data[offset + 7]
| (ulong)data[offset + 6] << 8
| (ulong)data[offset + 5] << 16
| (ulong)data[offset + 4] << 24
| (ulong)data[offset + 3] << 32
| (ulong)data[offset + 2] << 40
| (ulong)data[offset + 1] << 48
| (ulong)data[offset + 0] << 56;
| ((ulong)data[offset + 6] << 8)
| ((ulong)data[offset + 5] << 16)
| ((ulong)data[offset + 4] << 24)
| ((ulong)data[offset + 3] << 32)
| ((ulong)data[offset + 2] << 40)
| ((ulong)data[offset + 1] << 48)
| ((ulong)data[offset + 0] << 56);
}
#endregion
@@ -90,9 +90,9 @@ namespace SabreTools.Hashing
public static uint ReadLE32(byte[] data, int offset)
{
return (uint)(data[offset + 0]
| data[offset + 1] << 8
| data[offset + 2] << 16
| data[offset + 3] << 24);
| (data[offset + 1] << 8)
| (data[offset + 2] << 16)
| (data[offset + 3] << 24));
}
/// <summary>
@@ -101,13 +101,13 @@ namespace SabreTools.Hashing
public static ulong ReadLE64(byte[] data, int offset)
{
return data[offset + 0]
| (ulong)data[offset + 1] << 8
| (ulong)data[offset + 2] << 16
| (ulong)data[offset + 3] << 24
| (ulong)data[offset + 4] << 32
| (ulong)data[offset + 5] << 40
| (ulong)data[offset + 6] << 48
| (ulong)data[offset + 7] << 56;
| ((ulong)data[offset + 1] << 8)
| ((ulong)data[offset + 2] << 16)
| ((ulong)data[offset + 3] << 24)
| ((ulong)data[offset + 4] << 32)
| ((ulong)data[offset + 5] << 40)
| ((ulong)data[offset + 6] << 48)
| ((ulong)data[offset + 7] << 56);
}
#endregion

View File

@@ -31,7 +31,7 @@ namespace SabreTools.Hashing
// Get all file hashes
HashType[] standardHashTypes = [HashType.CRC32, HashType.MD5, HashType.SHA1];
var fileHashes = GetFileHashesAndSize(filename, standardHashTypes, out size);
if (fileHashes == null)
if (fileHashes is null)
return false;
// Assign the file hashes and return
@@ -58,7 +58,7 @@ namespace SabreTools.Hashing
// Get all file hashes
HashType[] standardHashTypes = [HashType.CRC32, HashType.MD5, HashType.SHA1];
var fileHashes = GetByteArrayHashesAndSize(array, standardHashTypes, out size);
if (fileHashes == null)
if (fileHashes is null)
return false;
// Assign the file hashes and return
@@ -85,7 +85,7 @@ namespace SabreTools.Hashing
// Get all file hashes
HashType[] standardHashTypes = [HashType.CRC32, HashType.MD5, HashType.SHA1];
var fileHashes = GetStreamHashesAndSize(stream, standardHashTypes, out size);
if (fileHashes == null)
if (fileHashes is null)
return false;
// Assign the file hashes and return
@@ -598,7 +598,7 @@ namespace SabreTools.Hashing
// Run the hashing
var hashers = GetStreamHashesInternal(input, hashTypes, leaveOpen, out size);
if (hashers == null)
if (hashers is null)
return null;
// Get the results
@@ -657,7 +657,7 @@ namespace SabreTools.Hashing
// Run the hashing
var hashers = GetStreamHashesInternal(input, hashTypes, leaveOpen, out size);
if (hashers == null)
if (hashers is null)
return null;
// Get the results

View File

@@ -133,7 +133,7 @@ namespace SabreTools.Hashing
/// <summary>
/// CRC 8-bit checksum
/// </summary>
/// <remarks>Identical to <see cref="CRC8_SMBUS"/>
/// <remarks>Identical to <see cref="CRC8_SMBUS"/>
CRC8,
/// <summary>
@@ -337,7 +337,7 @@ namespace SabreTools.Hashing
/// <summary>
/// CRC 16-bit checksum
/// </summary>
/// <remarks>Identical to <see cref="CRC16_ARC"/>
/// <remarks>Identical to <see cref="CRC16_ARC"/>
CRC16,
/// <summary>
@@ -582,7 +582,7 @@ namespace SabreTools.Hashing
/// <summary>
/// CRC 32-bit checksum
/// </summary>
/// <remarks>Identical to <see cref="CRC32_ISOHDLC"/>
/// <remarks>Identical to <see cref="CRC32_ISOHDLC"/>
CRC32,
/// <summary>
@@ -615,6 +615,11 @@ namespace SabreTools.Hashing
/// </summary>
CRC32_CKSUM,
/// <summary>
/// CRC 32-bit checksum (CRC-32/DVD-ROM-EDC)
/// </summary>
CRC32_DVDROMEDC,
/// <summary>
/// CRC 32-bit checksum (CRC-32/ISCSI)
/// </summary>
@@ -661,7 +666,7 @@ namespace SabreTools.Hashing
/// <summary>
/// CRC 64-bit checksum
/// </summary>
/// <remarks>Identical to <see cref="CRC64_ECMA182"/>
/// <remarks>Identical to <see cref="CRC64_ECMA182"/>
CRC64,
/// <summary>
@@ -840,7 +845,7 @@ namespace SabreTools.Hashing
/// <summary>
/// SHA3-512 hash
/// </summary>
SHA3_512,
SHA3_512,
/// <summary>
/// SHAKE128 SHA-3 family hash

View File

@@ -208,6 +208,7 @@ namespace SabreTools.Hashing
HashType.CRC32_BZIP2 => new Crc(StandardDefinitions.CRC32_BZIP2),
HashType.CRC32_CDROMEDC => new Crc(StandardDefinitions.CRC32_CDROMEDC),
HashType.CRC32_CKSUM => new Crc(StandardDefinitions.CRC32_CKSUM),
HashType.CRC32_DVDROMEDC => new Crc(StandardDefinitions.CRC32_DVDROMEDC),
HashType.CRC32_ISCSI => new Crc(StandardDefinitions.CRC32_ISCSI),
HashType.CRC32_ISOHDLC => new Crc(StandardDefinitions.CRC32_ISOHDLC),
HashType.CRC32_JAMCRC => new Crc(StandardDefinitions.CRC32_JAMCRC),
@@ -324,6 +325,10 @@ namespace SabreTools.Hashing
s256.AppendData(s256BufferSpan);
break;
#endif
default:
// No-op
break;
}
}
@@ -339,6 +344,9 @@ namespace SabreTools.Hashing
case HashAlgorithm ha:
ha.TransformFinalBlock(emptyBuffer, 0, 0);
break;
default:
// No-op
break;
}
}
@@ -347,15 +355,15 @@ namespace SabreTools.Hashing
/// </summary>
/// <param name="cr">Crc to get the value from</param>
/// <returns>String representing the CRC, null on error</returns>
private string? GetCRCVariableLengthString(Crc cr)
private static string? GetCRCVariableLengthString(Crc cr)
{
// Ignore null values
if (cr.Hash == null)
if (cr.Hash is null)
return null;
// Get the total number of characters needed
ulong hash = BytesToUInt64(cr.Hash);
int length = cr.Def.Width / 4 + (cr.Def.Width % 4 > 0 ? 1 : 0);
int length = (cr.Def.Width / 4) + (cr.Def.Width % 4 > 0 ? 1 : 0);
return hash.ToString($"x{length}");
}
@@ -364,10 +372,10 @@ namespace SabreTools.Hashing
/// </summary>
/// <param name="ss">SpamSum to get the value from</param>
/// <returns>String representing the SpamSum, null on error</returns>
private string? GetSpamSumBase64String(SpamSum.SpamSum ss)
private static string? GetSpamSumBase64String(SpamSum.SpamSum ss)
{
// Ignore null values
if (ss.Hash == null)
if (ss.Hash is null)
return null;
return System.Text.Encoding.ASCII.GetString(ss.Hash);

View File

@@ -7,7 +7,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
/// <summary>
/// Structure for xxHash-32 streaming API.
/// </summary>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
internal class XxHash32State
{
/// <summary>
@@ -137,7 +137,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
/// <summary>
/// Normal stripe processing routine.
///
///
/// This shuffles the bits so that any bit from <paramref name="input"/> impacts
/// several bits in <paramref name="acc"/>.
/// </summary>
@@ -154,7 +154,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
/// <summary>
/// Mixes all bits to finalize the hash.
///
///
/// The final mix ensures that all input bits have a chance to impact any bit in
/// the output digest, resulting in an unbiased distribution.
/// </summary>
@@ -170,7 +170,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
/// <summary>
/// Processes the last 0-15 bytes of @p ptr.
///
///
/// There may be up to 15 bytes remaining to consume from the input.
/// This final stage will digest them to ensure that all input bytes are present
/// in the final mix.

View File

@@ -7,7 +7,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
/// <summary>
/// Structure for xxHash-64 streaming API.
/// </summary>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
internal class XxHash64State
{
/// <summary>
@@ -134,7 +134,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
/// <summary>
/// Normal stripe processing routine.
///
///
/// This shuffles the bits so that any bit from @p input impacts
/// several bits in @p acc.
/// </summary>
@@ -153,13 +153,13 @@ namespace SabreTools.Hashing.NonCryptographicHash
{
val = Round(0, val);
acc ^= val;
acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4;
acc = (acc * XXH_PRIME64_1) + XXH_PRIME64_4;
return acc;
}
/// <summary>
/// Processes the last 0-31 bytes of @p ptr.
///
///
/// There may be up to 31 bytes remaining to consume from the input.
/// This final stage will digest them to ensure that all input bytes are present
/// in the final mix.
@@ -178,7 +178,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
ulong k1 = Round(0, ReadLE64(data, offset));
offset += 8;
hash ^= k1;
hash = RotateLeft64(hash, 27) * XXH_PRIME64_1 + XXH_PRIME64_4;
hash = (RotateLeft64(hash, 27) * XXH_PRIME64_1) + XXH_PRIME64_4;
length -= 8;
}
@@ -186,7 +186,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
{
hash ^= ReadLE32(data, offset) * XXH_PRIME64_1;
offset += 4;
hash = RotateLeft64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
hash = (RotateLeft64(hash, 23) * XXH_PRIME64_2) + XXH_PRIME64_3;
length -= 4;
}
@@ -202,7 +202,7 @@ namespace SabreTools.Hashing.NonCryptographicHash
/// <summary>
/// Mixes all bits to finalize the hash.
///
///
/// The final mix ensures that all input bits have a chance to impact any bit in
/// the output digest, resulting in an unbiased distribution.
/// </summary>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<IncludeSymbols>true</IncludeSymbols>
@@ -11,7 +11,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.5.1</Version>
<Version>1.6.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -30,8 +30,8 @@
<ItemGroup>
<PackageReference Include="Blake3" Version="1.1.0" Condition="$(TargetFramework.StartsWith(`net7`))" />
<PackageReference Include="Blake3" Version="2.0.0" Condition="$(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))" />
<PackageReference Include="System.IO.Hashing" Version="9.0.7" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net45`))" />
<PackageReference Include="Blake3" Version="2.0.0" Condition="$(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`)) OR $(TargetFramework.StartsWith(`net10`))" />
<PackageReference Include="System.IO.Hashing" Version="10.0.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net45`))" />
</ItemGroup>
</Project>

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Hashing.SpamSum
/// A blockhash contains a signature state for a specific (implicit) blocksize.
/// The blocksize is given by <see cref="SSDEEP_BS(uint)"/>
/// </summary>
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
internal class BlockhashContext
{
/// <summary>
@@ -20,7 +20,7 @@ namespace SabreTools.Hashing.SpamSum
public byte[] Digest { get; set; }
/// <summary>
/// Digest value at <see cref="HalfH"/>
/// Digest value at <see cref="HalfH"/>
/// </summary>
public byte HalfDigest { get; set; }

View File

@@ -8,7 +8,7 @@ internal static class Comparisons
/// <summary>
/// Regex to reduce any sequences longer than 3
/// </summary>
private static Regex _reduceRegex = new("(.)(?<=\\1\\1\\1\\1)", RegexOptions.Compiled);
private static readonly Regex _reduceRegex = new("(.)(?<=\\1\\1\\1\\1)", RegexOptions.Compiled);
/// <summary>
/// Compares how similar two SpamSums are to each other
@@ -17,7 +17,7 @@ internal static class Comparisons
/// <param name="second">Second hash to compare</param>
/// <returns>-1 on validity failure, 0 if they're not comparable, score from 0 (least similar) to 100 (most similar) otherwise.</returns>
/// <remarks>Implements ssdeep's fuzzy_compare</remarks>
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/df3b860f8918261b3faeec9c7d2c8a241089e6e6/fuzzy.c#L860"/>
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/df3b860f8918261b3faeec9c7d2c8a241089e6e6/fuzzy.c#L860"/>
public static int FuzzyCompare(string? first, string? second)
{
// If either input is invalid
@@ -163,9 +163,15 @@ internal static class Comparisons
secondTraverse[secondIndex + 1] = Math.Min(Math.Min(costA, costD), costR);
}
#pragma warning disable IDE0180 // Use tuple to swap values
#if NETCOREAPP || NETSTANDARD2_0_OR_GREATER
(secondTraverse, firstTraverse) = (firstTraverse, secondTraverse);
#else
var tempArray = firstTraverse;
firstTraverse = secondTraverse;
secondTraverse = tempArray;
#endif
#pragma warning restore IDE0180
}
long score = firstTraverse[second.Length];
@@ -173,13 +179,13 @@ internal static class Comparisons
const int spamSumLength = 64;
const int rollingWindow = 7;
const int minBlocksize = 3;
score = (score * spamSumLength) / (first.Length + second.Length);
score = score * spamSumLength / (first.Length + second.Length);
// Currently, the score ranges from 0-64 (64 being the length of a spamsum), with 0 being the strongest match
// and 64 being the weakest match.
// Change scale to 0-100
score = (100 * score) / spamSumLength;
score = 100 * score / spamSumLength;
// Invert scale so 0 is the weakest possible match and 100 is the strongest
score = 100 - score;

View File

@@ -2,8 +2,8 @@ using System.Text;
namespace SabreTools.Hashing.SpamSum
{
/// <see href="github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
/// <see href="github.com/ssdeep-project/ssdeep/blob/master/fuzzy.h"/>
/// <see href="github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
/// <see href="github.com/ssdeep-project/ssdeep/blob/master/fuzzy.h"/>
internal static class Constants
{
/// <summary>
@@ -27,7 +27,7 @@ namespace SabreTools.Hashing.SpamSum
/// The longest possible length for a fuzzy hash signature
/// (without the filename)
/// </summary>
public const int FUZZY_MAX_RESULT = 2 * SPAMSUM_LENGTH + 20;
public const int FUZZY_MAX_RESULT = (2 * SPAMSUM_LENGTH) + 20;
public const uint ROLLING_WINDOW = 7;

View File

@@ -3,7 +3,7 @@ using static SabreTools.Hashing.SpamSum.Constants;
namespace SabreTools.Hashing.SpamSum
{
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
internal class FuzzyState
{
public ulong TotalSize { get; set; }
@@ -85,7 +85,7 @@ namespace SabreTools.Hashing.SpamSum
// start_blocksize. Get rid of it.
++BHStart;
ReduceBorder *= 2;
RollMask = RollMask * 2 + 1;
RollMask = (RollMask * 2) + 1;
}
}
}

View File

@@ -2,7 +2,7 @@ using static SabreTools.Hashing.SpamSum.Constants;
namespace SabreTools.Hashing.SpamSum
{
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
internal class RollState
{
public byte[] Window { get; set; }
@@ -23,10 +23,10 @@ namespace SabreTools.Hashing.SpamSum
/// <summary>
/// A rolling hash, based on the Adler checksum. By using a rolling hash
/// we can perform auto resynchronisation after inserts/deletes.
///
///
/// Internally, H1 is the sum of the bytes in the window and H2
/// is the sum of the bytes times the index.
///
///
/// H3 is a shift/xor based rolling hash, and is mostly needed to ensure that
/// we can cope with large blocksize values.
/// </summary>

View File

@@ -2,9 +2,10 @@ using System;
using System.Text;
using static SabreTools.Hashing.SpamSum.Constants;
#pragma warning disable IDE0059 // Unnecessary assignment of a value
namespace SabreTools.Hashing.SpamSum
{
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
/// <see href="https://github.com/ssdeep-project/ssdeep/blob/master/fuzzy.c"/>
public class SpamSum : System.Security.Cryptography.HashAlgorithm
{
private FuzzyState _state;
@@ -54,7 +55,7 @@ namespace SabreTools.Hashing.SpamSum
protected override byte[] HashFinal()
{
string? digest = Finalize(0);
if (digest == null)
if (digest is null)
return [];
return Encoding.ASCII.GetBytes(digest.TrimEnd('\0'));
@@ -249,8 +250,8 @@ namespace SabreTools.Hashing.SpamSum
{
++bi;
i = (int)_state.BH[bi].DIndex;
if ((flags & FUZZY_FLAG_NOTRUNC) == 0 && i > SPAMSUM_LENGTH / 2 - 1)
i = SPAMSUM_LENGTH / 2 - 1;
if ((flags & FUZZY_FLAG_NOTRUNC) == 0 && i > (SPAMSUM_LENGTH / 2) - 1)
i = (SPAMSUM_LENGTH / 2) - 1;
if (i > remain)
return null;

View File

@@ -1,3 +1,4 @@
#pragma warning disable IDE0051 // Remove unused private members
namespace SabreTools.Hashing.XxHash
{
// https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h

View File

@@ -63,7 +63,7 @@ namespace SabreTools.Hashing.XxHash
/// <summary>
/// Mixes all bits to finalize the hash.
///
///
/// The final mix ensures that all input bits have a chance to impact any bit in
/// the output digest, resulting in an unbiased distribution.
/// </summary>
@@ -172,7 +172,7 @@ namespace SabreTools.Hashing.XxHash
if (length > 0)
return Len1To3Out64(data, offset, length, secret, seed);
return XXH64Avalanche(seed ^ (ReadLE64(secret, 56) ^ ReadLE64(secret, 64)));
return XXH64Avalanche(seed ^ ReadLE64(secret, 56) ^ ReadLE64(secret, 64));
}
public static ulong Mix16B(byte[] data, int offset, byte[] secret, int secretOffset, ulong seed)

View File

@@ -1,14 +1,16 @@
#pragma warning disable CS0169 // Private field is never used
#pragma warning disable CS0414 // Private field is assigned but its value is never used
#pragma warning disable CS0649 // Field is never assigned to
#pragma warning disable IDE0044 // Add readonly modifier
#pragma warning disable IDE0051 // Remove unused private members
#pragma warning disable IDE0052 // Remove unread private members
#pragma warning disable IDE0060 // Remove unused parameter
namespace SabreTools.Hashing.XxHash
{
// Handle unused private fields
#pragma warning disable CS0169
#pragma warning disable CS0414
#pragma warning disable CS0649
/// <summary>
/// Structure for XXH3 streaming API.
/// </summary>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
internal class XXH3_128State
{
/// <summary>
@@ -27,7 +29,7 @@ namespace SabreTools.Hashing.XxHash
private readonly byte[] _buffer = new byte[Constants.XXH3_INTERNALBUFFER_SIZE];
/// <summary>
/// The amount of memory in <see cref="_buffer"/>, <see cref="XXH32State._memsize"/>
/// The amount of memory in <see cref="_buffer"/>, <see cref="XXH32State._memsize"/>
/// </summary>
private uint _bufferedSize;

View File

@@ -1,14 +1,16 @@
#pragma warning disable CS0169 // Private field is never used
#pragma warning disable CS0414 // Private field is assigned but its value is never used
#pragma warning disable CS0649 // Field is never assigned to
#pragma warning disable IDE0044 // Add readonly modifier
#pragma warning disable IDE0051 // Remove unused private members
#pragma warning disable IDE0052 // Remove unread private members
#pragma warning disable IDE0060 // Remove unused parameter
namespace SabreTools.Hashing.XxHash
{
// Handle unused private fields
#pragma warning disable CS0169
#pragma warning disable CS0414
#pragma warning disable CS0649
/// <summary>
/// Structure for XXH3 streaming API.
/// </summary>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
/// <see href="https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h"/>
internal class XXH3_64State
{
/// <summary>
@@ -27,7 +29,7 @@ namespace SabreTools.Hashing.XxHash
private readonly byte[] _buffer = new byte[Constants.XXH3_INTERNALBUFFER_SIZE];
/// <summary>
/// The amount of memory in <see cref="_buffer"/>, <see cref="XXH32State._memsize"/>
/// The amount of memory in <see cref="_buffer"/>, <see cref="XXH32State._memsize"/>
/// </summary>
private uint _bufferedSize;

View File

@@ -221,6 +221,7 @@ namespace SabreTools.Hashing
{HashType.CRC32_BZIP2, [0x00, 0x00, 0x00, 0x00]},
{HashType.CRC32_CDROMEDC, [0x00, 0x00, 0x00, 0x00]},
{HashType.CRC32_CKSUM, [0xff, 0xff, 0xff, 0xff]},
{HashType.CRC32_DVDROMEDC, [0x00, 0x00, 0x00, 0x00]},
{HashType.CRC32_ISCSI, [0x00, 0x00, 0x00, 0x00]},
{HashType.CRC32_ISOHDLC, [0x00, 0x00, 0x00, 0x00]},
{HashType.CRC32_JAMCRC, [0xff, 0xff, 0xff, 0xff]},
@@ -523,6 +524,7 @@ namespace SabreTools.Hashing
{HashType.CRC32_BZIP2, "00000000"},
{HashType.CRC32_CDROMEDC, "00000000"},
{HashType.CRC32_CKSUM, "ffffffff"},
{HashType.CRC32_DVDROMEDC, "00000000"},
{HashType.CRC32_ISCSI, "00000000"},
{HashType.CRC32_ISOHDLC, "00000000"},
{HashType.CRC32_JAMCRC, "ffffffff"},

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# This batch file assumes the following:
# - .NET 9.0 (or newer) SDK is installed and in PATH
# - .NET 10.0 (or newer) SDK is installed and in PATH
# - zip is installed and in PATH
# - Git is installed and in PATH
#
@@ -49,18 +49,18 @@ echo " No archive (-a) $NO_ARCHIVE"
echo " "
# Create the build matrix arrays
FRAMEWORKS=("net9.0")
FRAMEWORKS=("net10.0")
RUNTIMES=("win-x86" "win-x64" "win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64")
# Use expanded lists, if requested
if [ $USE_ALL = true ]; then
FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0")
FRAMEWORKS=("net20" "net35" "net40" "net452" "net462" "net472" "net48" "netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
fi
# Create the filter arrays
SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0" "net9.0")
VALID_APPLE_FRAMEWORKS=("net6.0" "net7.0" "net8.0" "net9.0")
VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0")
SINGLE_FILE_CAPABLE=("net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
VALID_APPLE_FRAMEWORKS=("net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
VALID_CROSS_PLATFORM_FRAMEWORKS=("netcoreapp3.1" "net5.0" "net6.0" "net7.0" "net8.0" "net9.0" "net10.0")
VALID_CROSS_PLATFORM_RUNTIMES=("win-arm64" "linux-x64" "linux-arm64" "osx-x64" "osx-arm64")
# Only build if requested

View File

@@ -1,5 +1,5 @@
# This batch file assumes the following:
# - .NET 9.0 (or newer) SDK is installed and in PATH
# - .NET 10.0 (or newer) SDK is installed and in PATH
#
# If any of these are not satisfied, the operation may fail
# in an unpredictable way and result in an incomplete output.
@@ -38,18 +38,18 @@ Write-Host " No archive (-NoArchive) $NO_ARCHIVE"
Write-Host " "
# Create the build matrix arrays
$FRAMEWORKS = @('net9.0')
$FRAMEWORKS = @('net10.0')
$RUNTIMES = @('win-x86', 'win-x64', 'win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64')
# Use expanded lists, if requested
if ($USE_ALL.IsPresent) {
$FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0')
$FRAMEWORKS = @('net20', 'net35', 'net40', 'net452', 'net462', 'net472', 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
}
# Create the filter arrays
$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0')
$VALID_APPLE_FRAMEWORKS = @('net6.0', 'net7.0', 'net8.0', 'net9.0')
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0')
$SINGLE_FILE_CAPABLE = @('net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
$VALID_APPLE_FRAMEWORKS = @('net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
$VALID_CROSS_PLATFORM_FRAMEWORKS = @('netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0', 'net9.0', 'net10.0')
$VALID_CROSS_PLATFORM_RUNTIMES = @('win-arm64', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64')
# Only build if requested