Skip to content

Commit

Permalink
Merge pull request #98 from richardschneider/97-hashing-a-stream
Browse files Browse the repository at this point in the history
hashing a stream
  • Loading branch information
richardschneider authored Aug 8, 2019
2 parents 2ee2709 + 2ef53e2 commit b540c87
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 4 deletions.
21 changes: 20 additions & 1 deletion doc/articles/multihash.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,24 @@ data into a [CID](cid.md).

## Registry

The [hashing registry](xref:Ipfs.Registry.HashingAlgorithm) contains the metadata on a hashing algorithm. You can use
The [hashing registry](xref:Ipfs.Registry.HashingAlgorithm) contains the metadata on hashing algorithms. You can use
[Register](xref:Ipfs.Registry.HashingAlgorithm.Register*) to add a new hashing algorithm.

### Example

Using an hashing algorithm. Note that `ComputeHash` can take a byte array or a `Stream`.

```csharp
public void GetHasher()
{
using (var hasher = HashingAlgorithm.GetAlgorithm("sha3-256"))
{
Assert.IsNotNull(hasher);
var input = new byte[] { 0xe9 };
var expected = "f0d04dd1e6cfc29a4460d521796852f25d9ef8d28b44ee91ff5b759d72c1e6d6".ToHexBuffer();

var actual = hasher.ComputeHash(input);
CollectionAssert.AreEqual(expected, actual);
}
}
```
6 changes: 3 additions & 3 deletions src/CoreApi/IFileSystemApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public interface IFileSystemApi
/// Reads an existing IPFS file.
/// </summary>
/// <param name="path">
/// A path to an existing file, such as "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about"
/// An IPFS path to an existing file, such as "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about"
/// or "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V"
/// </param>
/// <param name="cancel">
Expand All @@ -130,7 +130,7 @@ public interface IFileSystemApi
/// Reads an existing IPFS file with the specified offset and length.
/// </summary>
/// <param name="path">
/// A path to an existing file, such as "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about"
/// Am IPFS path to an existing file, such as "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about"
/// or "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V"
/// </param>
/// <param name="offset">
Expand Down Expand Up @@ -173,7 +173,7 @@ public interface IFileSystemApi
/// Download IPFS objects as a TAR archive.
/// </summary>
/// <param name="path">
/// A path to an existing file or directory, such as "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about"
/// An IPFS path to an existing file or directory, such as "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about"
/// or "QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V"
/// </param>
/// <param name="compress">
Expand Down
25 changes: 25 additions & 0 deletions src/Registry/HashingAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,5 +223,30 @@ public static IEnumerable<HashingAlgorithm> All
get { return Names.Values; }
}

/// <summary>
/// Gets the <see cref="HashAlgorithm"/> with the specified IPFS multi-hash name.
/// </summary>
/// <param name="name">
/// The name of a hashing algorithm, see <see href="https://github.com/multiformats/multicodec/blob/master/table.csv"/>
/// for IPFS defined names.
/// </param>
/// <returns>
/// The hashing implementation associated with the <paramref name="name"/>.
/// </returns>
/// <exception cref="KeyNotFoundException">
/// When <paramref name="name"/> is not registered.
/// </exception>
public static HashAlgorithm GetAlgorithm(string name)
{
try
{
return HashingAlgorithm.Names[name].Hasher();
}
catch (KeyNotFoundException)
{
throw new KeyNotFoundException($"Hash algorithm '{name}' is not registered.");
}
}

}
}
15 changes: 15 additions & 0 deletions test/MultiHashTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,21 @@ public void CheckMultiHash()
}
}

[TestMethod]
public void CheckMultiHash_Stream()
{
foreach (var v in TestVectors)
{
if (v.Ignore) continue;
var bytes = Encoding.UTF8.GetBytes(v.Input);
using (var ms = new MemoryStream(bytes, false))
{
var mh = MultiHash.ComputeHash(ms, v.Algorithm);
Assert.AreEqual(v.Output, mh.ToArray().ToHexString(), v.Algorithm);
}
}
}

[TestMethod]
public void IdentityHash()
{
Expand Down
20 changes: 20 additions & 0 deletions test/Registry/HashingAlgorithmTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ namespace Ipfs.Registry
[TestClass]
public class HashingAlgorithmTest
{
[TestMethod]
public void GetHasher()
{
using (var hasher = HashingAlgorithm.GetAlgorithm("sha3-256"))
{
Assert.IsNotNull(hasher);
var input = new byte[] { 0xe9 };
var expected = "f0d04dd1e6cfc29a4460d521796852f25d9ef8d28b44ee91ff5b759d72c1e6d6".ToHexBuffer();

var actual = hasher.ComputeHash(input);
CollectionAssert.AreEqual(expected, actual);
}
}

[TestMethod]
public void GetHasher_Unknown()
{
ExceptionAssert.Throws<KeyNotFoundException>(() => HashingAlgorithm.GetAlgorithm("unknown"));
}

[TestMethod]
public void HashingAlgorithm_Bad_Name()
{
Expand Down

0 comments on commit b540c87

Please sign in to comment.