-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathMultiBase.cs
113 lines (105 loc) · 4.08 KB
/
MultiBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ipfs.Registry;
namespace Ipfs
{
/// <summary>
/// Self identifying base encodings.
/// </summary>
/// <remarks>
/// <b>MultiBase</b> is a protocol for distinguishing base encodings
/// and other simple string encodings.
/// See the <see cref="MultiBaseAlgorithm">registry</see> for supported algorithms.
/// </remarks>
/// <seealso href="https://github.com/multiformats/multibase"/>
public static class MultiBase
{
/// <summary>
/// The default multi-base algorithm is "base58btc".
/// </summary>
public const string DefaultAlgorithmName = "base58btc";
/// <summary>
/// Gets the <see cref="MultiBaseAlgorithm"/> with the specified IPFS multi-hash name.
/// </summary>
/// <param name="name">
/// The name of an algorithm, see
/// <see href="https://github.com/multiformats/multibase/blob/master/multibase.csv"/> for
/// for IPFS defined names.
/// </param>
/// <exception cref="KeyNotFoundException">
/// When <paramref name="name"/> is not registered.
/// </exception>
static MultiBaseAlgorithm GetAlgorithm(string name)
{
try
{
return MultiBaseAlgorithm.Names[name];
}
catch (KeyNotFoundException)
{
throw new KeyNotFoundException($"MutiBase algorithm '{name}' is not registered.");
}
}
/// <summary>
/// Converts an array of 8-bit unsigned integers to its equivalent string representation.
/// </summary>
/// <param name="bytes">
/// An array of 8-bit unsigned integers.
/// </param>
/// <param name="algorithmName">
/// The name of the multi-base algorithm to use. See <see href="https://github.com/multiformats/multibase/blob/master/multibase.csv"/>.
/// </param>
/// <returns>
/// A <see cref="string"/> starting with the algorithm's <see cref="MultiBaseAlgorithm.Code"/> and
/// followed by the encoded string representation of the <paramref name="bytes"/>.
/// </returns>
/// <exception cref="KeyNotFoundException">
/// When <paramref name="algorithmName"/> is not registered.
/// </exception>
public static string Encode(byte[] bytes, string algorithmName = DefaultAlgorithmName)
{
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
var alg = GetAlgorithm(algorithmName);
return alg.Code + alg.Encode(bytes);
}
/// <summary>
/// Converts the specified <see cref="string"/>, which encodes binary data,
/// to an equivalent 8-bit unsigned integer array.
/// </summary>
/// <param name="s">
/// The multi-base string to convert.
/// </param>
/// <returns>
/// An array of 8-bit unsigned integers that is equivalent to <paramref name="s"/>.
/// </returns>
/// <exception cref="FormatException">
/// When the <paramref name="s"/> can not be decoded.
/// </exception>
public static byte[] Decode(string s)
{
if (string.IsNullOrWhiteSpace(s))
{
throw new ArgumentNullException("s");
}
MultiBaseAlgorithm.Codes.TryGetValue(s[0], out MultiBaseAlgorithm alg);
if (alg == null)
{
throw new FormatException($"MultiBase '{s}' is invalid. The code is not registered.");
}
try
{
return alg.Decode(s.Substring(1));
}
catch (Exception e)
{
throw new FormatException($"MultiBase '{s}' is invalid; decode failed.", e);
}
}
}
}