Skip to content

Commit

Permalink
Update Docs
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-techkid committed Nov 10, 2024
1 parent 1ffe40f commit 1350fde
Show file tree
Hide file tree
Showing 30 changed files with 2,087 additions and 24 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
# HashingHandler
# HashingHandler

A C# library containing abstract classes for hashing data of various types.

View & Download this project on [NuGet](https://www.nuget.org/packages/HashingHandler/).

View the documentation for this project at [the website](https://simon-techkid.github.io/HashingHandler/).
22 changes: 12 additions & 10 deletions docfx/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@
}
],
"output": "_site",
"template": [
"default",
"modern"
],
"globalMetadata": {
"_appName": "HashingHandler",
"_appTitle": "HashingHandler",
"_enableSearch": true,
"pdf": true
}
"template": ["default", "templates/singulinkfx"],
"globalMetadata": {
"_appTitle": "HashingHandler",
"_appName": "HashingHandler",
"_appFooter": "<strong>Made with ♥ by Simon Field</strong>",
"_copyrightFooter": "© Simon Field. All rights reserved.",
"_enableSearch": true,
"_disableSideFilter": false,
"_enableNewTab": true,
"_disableContribution": false,
"_disableBreadcrumb": false,
}
}
}
155 changes: 155 additions & 0 deletions docfx/docs/algorithms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Algorithms

Algorithms in HashingHandler implement IHashingAlgorithm or IHashingAlgorithmAsync. Implementers of IHashingAlgorithmAsync also implement IHashingAlgorithm. IHashingAlgorithm provides synchronous hashing algorithm computation, and IHashingAlgorithmAsync provides both synchronous and asynchronous computation support.

`HashingAlgorithmBase` is the primary base class for implementations of `IHashingAlgorithm` and `IHashingAlgorithmAsync`. It provides support for both synchronous and asynchronous hash computation, using `protected` methods `byte[] ComputeHash()` and `Task<byte[]> ComputeHashAsync()`, as well as synchronous and asynchronous checksum computation of those hashes, using `public` methods `string ComputeHash()` and `Task<string> ComputeHashAsync()`.

## Variants

### IHashingAlgorithm

`IHashingAlgorithm<T>` is used for accessing hash algorithm classes. These classes allow the hashing of byte arrays (`byte[]`), producing `string` checksums of the given data.

### IHashingAlgorithmAsync

`IHashingAlgorithmAsync<T>` allows the asynchronous use of `IHashingAlgorithm<T>`. It implements `IHashingAlgorithm<T>`, so objects capable of asynchronous computation are also able to leverage synchronous methods.

## HashingCrypto and HashingNonCrypto

HashingHandler contains base classes for creating hashes using its `HashingCrypto` and `HashingNonCrypto` classes, allowing hash creation using [HashAlgorithm](https://learn.microsoft.com/dotnet/api/system.security.cryptography.hashalgorithm) and [NonCryptographicHashAlgorithm](https://learn.microsoft.com/dotnet/api/system.io.hashing.noncryptographichashalgorithm), respectively.

Both of these classes implement `IHashingAlgorithm<string>` and `IHashingAlgorithmAsync<string>` because they inherit `HashingNonCrypto<string>` and `HashingAlgorithmBase<string>`. This allows you to create common functionality across your program by using the shared methods in different contexts.

### Getting Started

To get started using `HashingCrypto` and `HashingNonCrypto` abstract classes in your program, you must create a class that implements one of these. Below are samples that allow calculation of SHA256 and XXH3 hashes using both `HashAlgorithm` and `NonCryptographicHashAlgorithm` abstract classes.

In your class implementing `HashingCrypto` or `HashingNonCrypto`, you must provide a method, `GetAlgorithm()`, that returns an instance of a hashing class (ie. `SHA256` or `XxHash3`) derived from either `HashAlgorithm` or `NonCryptographicHashAlgorithm`, respectively. This instance will then be used by the base, implemented class to create hashes using those algorithms.

See the sample implementations below of each.

## Samples

After creating a class that inherits `IHashingAlgorithm<T>` (including the below samples), you are able to compute hashes for data of type `T`, using the `IHashingAlgorithm<T>.ComputeHash()` method. This method returns a `string` of the hash of the data.

#### HashingCrypto

```
class SHA256Hasher : HashingCrypto<string>
{
protected override HashAlgorithm GetAlgorithm()
{
return SHA256.Create(); // Returns new SHA256 object
}
}
```

To create a hash using the SHA256 algorithm, construct this `SHA256Hasher` class.

It can be cast to `IHashingAlgorithm`:
```
IHashingAlgorithm<string> sha256 = new SHA256Hasher();
```

It can also be cast to `IHashingAlgorithmAsync` for asynchronous use, because `HashingCrypto` implements it.
```
IHashingAlgorithmAsync<string> sha256Async = new SHA256Hasher();
```

#### HashingNonCrypto

```
class XXH3Hasher(long seed = 0) : HashingNonCrypto<string>
{
private readonly long _seed = seed; // XxHash3 allows a seed, so we will add seed support to our class
protected override NonCryptographicHashAlgorithm GetAlgorithm()
{
return new XxHash3(_seed);
}
}
```

To create a hash using the XXH3 algorithm, construct this `XXH3Hasher` class.

It can be cast to `IHashingAlgorithm`:
```
IHashingAlgorithm<string> xxh3 = new XXH3Hasher();
```

It can also be cast to `IHashingAlgorithmAsync` for asynchronous use, because `HashingNonCrypto` implements it.
```
IHashingAlgorithmAsync<string> xxh3Async = new XXH3Hasher();
```

#### Create Your Own

To create your own hashing algorithm, create a class implementing `IHashingAlgorithm` or `IHashingAlgorithmAsync`. Remember, `IHashingAlgorithmAsync` implements `IHashingAlgorithm`, so you must provide a synchronous implementation for it!

I've chosen to inherit `HashingAlgorithmBase<T>`, because it provides both asynchronous and synchronous support in the base class. The below example provides a synchronous implementation.

By inheriting `HashingAlgorithmBase`, you make this `XORHash` class an `IHashingAlgorithm<T>` and `IHashingAlgorithmAsync<T>`.

The below example is a simple XOR hash algorithm:

```
class XORHash : HashingAlgorithmBase<object>
{
protected override byte[] ComputeHash(byte[] bytes)
{
// Specify the length of the payload to be hashed.
int payloadLength = bytes.Length; // Let's hash the entire payload.
// Specify the length of the returned hash.
int hashLength = 8; // 8 bytes, 16 characters
// Initialize result array to hold the hash of specified length
byte[] result = new byte[hashLength];
// Perform XOR on the bytes, distributing across each position in result
for (int i = 0; i < payloadLength; i++)
{
result[i % hashLength] ^= bytes[i];
}
return result;
}
}
```

To create a hash using this sample algorithm, construct this `XORHash` class.

It can be cast to `IHashingAlgorithm`:
```
IHashingAlgorithm<object> xor = new XORHash();
```

It can also be cast to `IHashingAlgorithmAsync` for asynchronous use, because `HashingAlgorithmBase` implements it.
```
IHashingAlgorithmAsync<object> xor = new XORHash();
```

Because we didn't override `HashingAlgorithmBase.ComputeHashAsync()` in the above sample implementation, any calls to `xor.ComputeHashAsync()` will use the default implementation, a `Task.Run()` of the synchronous implementation, `ComputeHash()`. If you'd like to create a specific asynchronous implementation, override `ComputeHashAsync()`.

### Conclusion

After creating the `IHashingAlgorithm<T>` or `IHashingAlgorithmAsync<T>` implementing object, you can perform hashing using the methods of `IHashingAlgorithm<T>` or `IHashingAlgorithmAsync<T>`, respectively.

```
// Create an IHashingProvider<T>, where T matches the type of your IHashingAlgorithm<T>.
// Assume we have instantiated an IHashingProvider<string> called 'provider'
// See the above samples on how to create an IHashingAlgorithm.
// Assume we have instantiated an IHashingAlgorithm<string> called 'algorithm'
string textPayload = "Hello World!";
return algorithm.ComputeHash(textPayload, provider);
```

We can also do it asynchronously, if our `algorithm` instance is `IHashingAlgorithmAsync<string>`

```
// Simulated asynchronous method below by using GetAwaiter().GetResult()
return algorithm.ComputeHashAsync(textPayload, provider).GetAwaiter().GetResult();
```

Remember, `IHashingAlgorithmAsync<T>` implements `IHashingAlgorithm<T>`, so you can perform synchronous hashing using an asynchronous hashing capable object using the methods of `IHashingAlgorithm<T>` on an `IHashingAlgorithmAsync<T>`.
1 change: 0 additions & 1 deletion docfx/docs/getting-started.md

This file was deleted.

1 change: 0 additions & 1 deletion docfx/docs/introduction.md

This file was deleted.

62 changes: 62 additions & 0 deletions docfx/docs/providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Providers

Providers in HashingHandler implement `IHashingProvider<T>` or `IHashingProviderAsync<T>`. Implementers of `IHashingProviderAsync<T>` also implement `IHashingProvider<T>`.

## Variants

### IHashingProvider

`IHashingProvider<T>` is used when an object can convert the data to be hashed of type `T` to a byte array (`byte[]`), so that the byte array can serve as a common type in all hash operations.

### IHashingProviderAsync

`IHashingProviderAsync<T>` is offered when an object of type `T` can be converted to a byte array asynchronously. `IHashingProviderAsync<T>` implements `IHashingProvider<T>`, so objects that are capable of handling asynchronous conversions are also able to leverage the synchronous methods of `IHashingProvider<T>`.

## Examples

You can find several examples of data types that you may want to create hashes for.

### Strings

HashingHandler contains a built-in base class to serve as an `IHashingProvider<T>` for `string` types, `StringHashProviderBase<T>`. Implementers of `StringHashProviderBase<T>` must define how to convert the data of type `T` to a `string`. The base class, `StringHashProviderBase` handles conversion of this string (using the method `ConvertToString`) to bytes, using a byte encoding.

Adding the below class to your program, which implements `StringHashProviderBase`, will provide a structure for hashing `string` instances.

```
class StringProvider : StringHashProviderBase<string>
{
protected override string ConvertToString(string data)
{
return data; // Already string, no conversion necessary
}
// Below is not a required field, but overriding it in your class will allow you to use other byte encodings than the default, UTF8.
protected override Encoding HashedDataEncoding => Encoding.UTF16
}
```

Because this `StringProvider` class inherits `StringHashProviderBase`, it also implements `IHashingProvider`.

To create a provider for converting the `string` data type to `byte[]` for hashing later, construct the example `StringProvider` class.

```
IHashingProvider<string> provider = new StringProvider();
```

You now have an `IHashingProvider<string>` that can be passed to an `IHashingAlgorithm<string>` to create a hash.

```
// Assume we have initialized the provider as well as an IHashingAlgorithm<string> above.
// The IHashingProvider<string> instance is called 'provider'
// The IHashingAlgorithm<string> instance is called 'algorithm'
string testPayload = "Hello World!";
string testHash = algorithm.ComputeHash(testPayload, provider);
Console.WriteLine(testHash);
```

We can compute the hash on another thread, if you've got an `IHashingAlgorithmAsync<string>`. Let's call the instance of the algorithm `algorithm`.

```
string testHash = algorithm.ComputeHashAsync(testPayload, provider).GetAwaiter().GetResult();
```
8 changes: 4 additions & 4 deletions docfx/docs/toc.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
- name: Introduction
href: introduction.md
- name: Getting Started
href: getting-started.md
- name: Algorithms
href: algorithms.md
- name: Providers
href: providers.md
8 changes: 4 additions & 4 deletions docfx/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
_layout: landing
---

# This is the **HOMEPAGE**.
# HashingHandler

Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files.
A C# library containing abstract classes for hashing data of various types.

## Quick Start Notes:
View & Download this project on [NuGet](https://www.nuget.org/packages/HashingHandler/).

1. Add images to the *images* folder if the file is referencing an image.
View the source code for this project at [GitHub](https://github.com/simon-techkid/HashingHandler/).
74 changes: 74 additions & 0 deletions docfx/templates/singulinkfx/layout/_master.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
{{!include(/^styles/.*/)}}
{{!include(/^fonts/.*/)}}
{{!include(favicon.ico)}}
{{!include(logo.svg)}}
{{!include(search-stopwords.json)}}
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
{{>partials/head}}

<body>
<!-- Header required for docfx anchor scroll to work -->
<header id="head"></header>
<div class="top-navbar">
<a class="burger-icon" onclick="toggleMenu()">
<svg name="Hamburger"
style="vertical-align: middle;"
width="34" height="34" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M20 6H4V9H20V6ZM4 10.999H20V13.999H4V10.999ZM4 15.999H20V18.999H4V15.999Z"></path></svg>
</a>

{{>partials/logo}}
</div>

<div class="body-content">
<div id="blackout" class="blackout" onclick="toggleMenu()"></div>

<nav id="sidebar" role="navigation">
<div class="sidebar">
{{>partials/navbar}}
<div class="sidebar-item-separator"></div>
{{^_disableToc}}
{{>partials/toc}}
{{/_disableToc}}
</div>
{{>partials/footer}}
</nav>

<main class="main-panel">
{{#_enableSearch}}
{{>partials/searchResults}}
{{/_enableSearch}}



<div role="main" class="hide-when-search" >
{{^_disableBreadcrumb}}
{{>partials/breadcrumb}}
{{/_disableBreadcrumb}}

{{^_disableContribution}}
<div id="contribution">
{{#docurl}}
<a href="{{docurl}}" class="contribution-link">{{__global.improveThisDoc}}</a>
{{/docurl}}
</div>
{{/_disableContribution}}

<article class="content wrap" id="_content" data-uid="{{uid}}">
{{!body}}
</article>
</div>

{{#_copyrightFooter}}
<div class="copyright-footer">
<span>{{_copyrightFooter}}</span>
</div>
{{/_copyrightFooter}}
</main>
</div>

{{>partials/scripts}}
</body>
</html>
4 changes: 4 additions & 0 deletions docfx/templates/singulinkfx/partials/footer.tmpl.partial
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="footer">
{{{_appFooter}}}
{{^_appFooter}}<strong><a href='https://dotnet.github.io/docfx/'>DocFX</a> + <a href='https://www.singulink.com'>Singulink</a> = ♥</strong>{{/_appFooter}}
</div>
23 changes: 23 additions & 0 deletions docfx/templates/singulinkfx/partials/head.tmpl.partial
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="{{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}">
<meta name="generator" content="docfx {{_docfxVersion}}">
{{#_description}}<meta name="description" content="{{_description}}">{{/_description}}
<link rel="shortcut icon" href="{{_rel}}{{{_appFaviconPath}}}{{^_appFaviconPath}}favicon.ico{{/_appFaviconPath}}">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/night-owl.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css" integrity="sha384-EvBWSlnoFgZlXJvpzS+MAUEjvN7+gcCwH+qh7GRFOGgZO0PuwOFro7qPOJnLfe7l" crossorigin="anonymous">
<link rel="stylesheet" href="{{_rel}}styles/config.css">
<link rel="stylesheet" href="{{_rel}}styles/singulink.css">
<link rel="stylesheet" href="{{_rel}}styles/main.css">
<meta property="docfx:navrel" content="{{_navRel}}">
<meta property="docfx:tocrel" content="{{_tocRel}}">
{{#_noindex}}<meta name="searchOption" content="noindex">{{/_noindex}}
{{#_enableSearch}}<meta property="docfx:rel" content="{{_rel}}">{{/_enableSearch}}
{{#_enableNewTab}}<meta property="docfx:newtab" content="true">{{/_enableNewTab}}
</head>
Loading

0 comments on commit 1350fde

Please sign in to comment.