├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── test.yml ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── SimpleBase.sln ├── SimpleBase.snk ├── benchmark ├── App.config ├── Benchmark.csproj ├── DecoderBenchmarks.cs ├── EncoderBenchmarks.cs ├── Program.cs └── Properties │ ├── AssemblyInfo.cs │ └── launchSettings.json ├── docs ├── index.md ├── simplebase.base16.md ├── simplebase.base16alphabet.md ├── simplebase.base256emoji.md ├── simplebase.base32.md ├── simplebase.base32alphabet.md ├── simplebase.base36.md ├── simplebase.base36alphabet.md ├── simplebase.base45.md ├── simplebase.base45alphabet.md ├── simplebase.base58.md ├── simplebase.base58alphabet.md ├── simplebase.base62.md ├── simplebase.base62alphabet.md ├── simplebase.base85.md ├── simplebase.base85alphabet.md ├── simplebase.base85ipv6.md ├── simplebase.codingalphabet.md ├── simplebase.dividingcoder-1.md ├── simplebase.ibasecoder.md ├── simplebase.ibasestreamcoder.md ├── simplebase.icodingalphabet.md ├── simplebase.inonallocatingbasecoder.md ├── simplebase.inumericbasecoder.md ├── simplebase.monerobase58.md ├── simplebase.multibase.md ├── simplebase.multibaseencoding.md └── simplebase.paddingposition.md ├── generate_docs.ps1 ├── pack.cmd ├── pack.sh ├── push.cmd ├── push.sh ├── src ├── AliasedBase32Alphabet.cs ├── Base10.cs ├── Base10Alphabet.cs ├── Base16.cs ├── Base16Alphabet.cs ├── Base2.cs ├── Base256Emoji.cs ├── Base32.cs ├── Base32Alphabet.cs ├── Base36.cs ├── Base36Alphabet.cs ├── Base45.cs ├── Base45Alphabet.cs ├── Base58.cs ├── Base58Alphabet.cs ├── Base62.cs ├── Base62Alphabet.cs ├── Base64.cs ├── Base8.cs ├── Base85.cs ├── Base85Alphabet.cs ├── Base85Ipv6.cs ├── Bits.cs ├── CharMap.cs ├── CodingAlphabet.cs ├── DividingCoder.cs ├── IBaseCoder.cs ├── IBaseStreamCoder.cs ├── ICodingAlphabet.cs ├── INonAllocatingBaseCoder.cs ├── INumericBaseCoder.cs ├── MoneroBase58.cs ├── Multibase.cs ├── MultibaseEncoding.cs ├── PaddingPosition.cs ├── Properties │ └── AssemblyInfo.cs ├── PublicAPI.Shipped.txt ├── PublicAPI.Unshipped.txt ├── SimpleBase.csproj ├── StreamHelper.cs └── stylecop.json └── test ├── .editorconfig ├── Base10Test.cs ├── Base16 ├── Base16Test.cs └── LegacyTest.cs ├── Base256EmojiTest.cs ├── Base2Test.cs ├── Base32 ├── Base32AlphabetTest.cs ├── Bech32Test.cs ├── CrockfordTest.cs ├── ExtendedHexTest.cs ├── FileCoinTest.cs ├── GeohashTest.cs ├── Rfc4648Test.cs └── ZBase32Test.cs ├── Base36 ├── LowerCaseTest.cs └── UpperCaseTest.cs ├── Base45 └── DefaultTest.cs ├── Base58 ├── Base58AlphabetTest.cs ├── Base58CheckTest.cs ├── BitcoinTest.cs ├── Cb58Test.cs ├── FlickrTest.cs ├── MoneroBase58Test.cs └── RippleTest.cs ├── Base62 ├── DefaultTest.cs └── LowerFirstTest.cs ├── Base85 ├── Ascii85Test.cs ├── Base85AlphabetTest.cs ├── Rfc1924Test.cs └── Z85Test.cs ├── Base8Test.cs ├── CodingAlphabetTest.cs ├── EncodingAlphabetTest.cs ├── GlobalSuppressions.cs ├── LICENSE.avalanchego.txt ├── LICENSE.monero-rs.txt ├── Multibase └── MultibaseTest.cs └── SimpleBase.Tests.csproj /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ssg] 4 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Build, Test, and Deploy 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout code 10 | uses: actions/checkout@v1 11 | 12 | - name: Setup .NET 13 | uses: actions/setup-dotnet@v3 14 | with: 15 | dotnet-version: 8.0.x 16 | 17 | - name: Build 18 | run: dotnet build --configuration Release 19 | 20 | - name: Run tests 21 | run: dotnet test --no-build --configuration Release 22 | 23 | - name: Pack 24 | run: dotnet pack src --no-build --configuration Release --output ./nupkg 25 | 26 | - name: Publish to NuGet 27 | if: startsWith(github.ref, 'refs/tags/') 28 | run: dotnet nuget push ./nupkg/*.nupkg -k ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json 29 | 30 | - name: Publish to GitHub Packages 31 | if: startsWith(github.ref, 'refs/tags/') 32 | run: dotnet nuget push ./nupkg/*.nupkg -k ${{ secrets.GPM_TOKEN }} -s https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.suo 2 | *.user 3 | bin/ 4 | obj/ 5 | _NCrunch*/ 6 | packages/ 7 | *.ncrunch* 8 | *.nupkg 9 | *.psess 10 | *.vspx 11 | .vs/ 12 | *.userprefs 13 | SimpleBase.xml 14 | .idea/ 15 | BenchmarkDotNet.Artifacts/ -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/benchmark/bin/Debug/netcoreapp2.1/Benchmark.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}/benchmark", 16 | // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window 17 | "console": "internalConsole", 18 | "stopAtEntry": false, 19 | "internalConsoleOptions": "openOnSessionStart" 20 | }, 21 | { 22 | "name": "Launch (RELEASE)", 23 | "type": "coreclr", 24 | "request": "launch", 25 | "preLaunchTask": "build release", 26 | // If you have changed target frameworks, make sure to update the program path. 27 | "program": "${workspaceFolder}/benchmark/bin/Release/netcoreapp2.1/Benchmark.dll", 28 | "args": [], 29 | "cwd": "${workspaceFolder}/benchmark", 30 | // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window 31 | "console": "internalConsole", 32 | "stopAtEntry": false, 33 | "internalConsoleOptions": "openOnSessionStart" 34 | }, 35 | { 36 | "name": "Attach", 37 | "type": "coreclr", 38 | "request": "attach", 39 | "processId": "${command:pickProcess}" 40 | } 41 | ,] 42 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}", 11 | "/p:GenerateFullPaths=true" 12 | ], 13 | "problemMatcher": "$msCompile", 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | }, 19 | { 20 | "label": "build release", 21 | "command": "dotnet", 22 | "type": "process", 23 | "args": [ 24 | "build", 25 | "${workspaceFolder}", 26 | "-c", 27 | "Release", 28 | "/p:GenerateFullPaths=true" 29 | ], 30 | "problemMatcher": "$msCompile", 31 | "group": "build" 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 5.4.1 2 | 3 | ## Fixes 4 | - Remove unused function from CodingAlphabet 5 | 6 | # 5.4.0 7 | 8 | ## New features 9 | - CodingAlphabet now supports case-insensitivity 10 | 11 | ## Improvements 12 | - Multibase decoding now supports case-insensitive decoding 13 | - Base36 decoding is now case-insensitive 14 | 15 | ## Fixes 16 | - Base32 case-insensitive decoding now works correctly 17 | 18 | # 5.3.0 19 | 20 | ## New features 21 | - AOT and trimming compatibility 22 | - Base2, Base8, and Base10 support 23 | 24 | ## Improvements 25 | - `Base58` now uses `DividingCoder` under the hood for less code duplication 26 | - Several implementations now take bytesWritten into account when returning buffers, reducing the possibility of returning a buffer larger than necessary. 27 | 28 | # 5.2.0 29 | 30 | ## New features 31 | - Multibase support for Base36 (upper and lower) 32 | 33 | # 5.1.0 34 | 35 | ## New features 36 | - Base36 37 | - Base256Emoji 38 | 39 | # 5.0.0 40 | 41 | ## Breaking changes 42 | - TryDecode/TryEncode methods no longer throw 43 | - Base85 methods with `Ipv6` in them renamed to `IPv6` to match with .NET 44 | - `numBytesWritten` parameters have all been renamed to `bytesWritten` to match with .NET 45 | - The target framework was changed to .NET 8.0 around 4.2.0, but the version change did not 46 | reflect that breaking change, although in practice it shouldn't cause many issues. 47 | 48 | ## New features 49 | - Base62 50 | - Base45 51 | - Multibase now supports Base45 52 | - Base32 now has a non-throwing `TryDecodeUInt64()` method 53 | 54 | ## Improvements 55 | - `Multibase.Encode()` now allocates less memory 56 | 57 | # 4.3.0 58 | 59 | ## New features 60 | - Added Multibase support that supports several Base16, Base32, Base58, and Base64 variants. 61 | 62 | ## Improvements 63 | - Eliminated more memory allocations (by @Henr1k80)) 64 | 65 | # 4.2.0 66 | 67 | ## New features 68 | - Monero Base58 algorithm support with `MoneroBase58` class. It can be accessed as `Base58.Monero` 69 | 70 | ## Improvements 71 | - Eliminate some memory allocations 72 | 73 | ## Fixes 74 | - Throw `ArgumentOutOfRangeException` with correct parameters in `Base32.DecodeInt64()` 75 | 76 | # 4.1.0 77 | 78 | ## Improvements 79 | - Reduce heap allocations (by @Henr1k80) 80 | 81 | # 4.0.2 82 | 83 | ## Fixes 84 | - Fixes #59 - Base32's `Encode(ulong)` and `DecodeUInt64()` works consistently among platforms with different endianness 85 | 86 | # 4.0.1 87 | 88 | ## Fixes 89 | - Fixes #58 - `Encode(long)` failing -- reported by Pascal Schwarz <@pschwarzpp> 90 | 91 | # 4.0.0 92 | 93 | ## Breaking changes 94 | - This version is built with .NET 6 SDK. 95 | - Benchmark now uses BenchmarkDotNet. 96 | - Changed interface names from Encoder to Coder to signify encoding and 97 | decoding functionality better. 98 | - Removed obsolete methods. 99 | - Simple (aka allocating) versions of `Decode()` will now return `byte[]`'s instead of `Span`'s for correct 100 | ownership semantics. It's even possible that some copying may be avoided in certain scenarios. 101 | - `Base16.TryDecode()` doesn't throw on invalid input, but returns `false` instead. 102 | - `Base32.Decode()` throws separate exceptions for encountered failures. 103 | 104 | ## New features 105 | - Added [Bech32](https://en.bitcoin.it/wiki/Bech32) flavor to Base32 106 | - Added RFC 1924 (IPv6) flavor to Base85 along with 107 | EncodeIpv6 and DecodeIpv6 functions https://tools.ietf.org/html/rfc1924 108 | - Added `Base58.Bitcoin.EncodeCheck()` and `Base58.Bitcoin.TryDecodeCheck()` methods. 109 | - Added `Base58.Bitcoin.EncodeCb58()` and `Base58.Bitcoin.TryDecodeCb58()` methods. 110 | 111 | ## Improvements 112 | - Added more buffer overflow detection to Base32 coder 113 | - Removed all unsafe code. New Span-based optimizations make the code come close to unsafe perf. 114 | - Removed slow and hard to read optimizations like bit shift operations for multiplication and division 115 | where compiler almost always does a better job of optimizing. 116 | 117 | ## Fixes 118 | - Fixed output buffer was too small error for certain Base58 cases. 119 | - Avoid redundant memory copy operations 120 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | 4.x and 5.x versions are supported for security related updates. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | You can send me an email (link in [profile](https://github.com/ssg)) for 10 | security sensitive issues. 11 | -------------------------------------------------------------------------------- /SimpleBase.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32210.238 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleBase", "src\SimpleBase.csproj", "{A9C1CF86-32B3-40E6-A51A-3E6D17C15EE3}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleBase.Tests", "test\SimpleBase.Tests.csproj", "{617BA86D-31E2-41EA-A1C8-E37602D58C07}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4ECCE094-D6EC-4938-A209-FA9B78AED7DA}" 11 | ProjectSection(SolutionItems) = preProject 12 | .editorconfig = .editorconfig 13 | .gitignore = .gitignore 14 | CHANGELOG.md = CHANGELOG.md 15 | LICENSE.txt = LICENSE.txt 16 | pack.cmd = pack.cmd 17 | pack.sh = pack.sh 18 | push.cmd = push.cmd 19 | push.sh = push.sh 20 | README.md = README.md 21 | SimpleBase.snk = SimpleBase.snk 22 | .github\workflows\test.yml = .github\workflows\test.yml 23 | EndProjectSection 24 | EndProject 25 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmark", "benchmark\Benchmark.csproj", "{83A36BC1-8195-4595-A59D-E6B66AD47B97}" 26 | EndProject 27 | Global 28 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 29 | Debug|Any CPU = Debug|Any CPU 30 | Release|Any CPU = Release|Any CPU 31 | EndGlobalSection 32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 33 | {A9C1CF86-32B3-40E6-A51A-3E6D17C15EE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {A9C1CF86-32B3-40E6-A51A-3E6D17C15EE3}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {A9C1CF86-32B3-40E6-A51A-3E6D17C15EE3}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {A9C1CF86-32B3-40E6-A51A-3E6D17C15EE3}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {617BA86D-31E2-41EA-A1C8-E37602D58C07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {617BA86D-31E2-41EA-A1C8-E37602D58C07}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {617BA86D-31E2-41EA-A1C8-E37602D58C07}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {617BA86D-31E2-41EA-A1C8-E37602D58C07}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {83A36BC1-8195-4595-A59D-E6B66AD47B97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {83A36BC1-8195-4595-A59D-E6B66AD47B97}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {83A36BC1-8195-4595-A59D-E6B66AD47B97}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {83A36BC1-8195-4595-A59D-E6B66AD47B97}.Release|Any CPU.Build.0 = Release|Any CPU 45 | EndGlobalSection 46 | GlobalSection(SolutionProperties) = preSolution 47 | HideSolutionNode = FALSE 48 | EndGlobalSection 49 | GlobalSection(ExtensibilityGlobals) = postSolution 50 | SolutionGuid = {4816E756-0FA5-40C5-9CCC-C9BD3C93FC1C} 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /SimpleBase.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ssg/SimpleBase/0115230d1294bfbaa81682cd932aba4df0bf05cf/SimpleBase.snk -------------------------------------------------------------------------------- /benchmark/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /benchmark/Benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | net8.0 5 | false 6 | true 7 | ..\SimpleBase.snk 8 | false 9 | latest 10 | enable 11 | AnyCPU 12 | Exe 13 | IDE0079 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /benchmark/DecoderBenchmarks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using SimpleBase; 6 | 7 | namespace Benchmark; 8 | 9 | [MarkdownExporterAttribute.GitHub] 10 | [MemoryDiagnoser] 11 | public class DecoderBenchmarks 12 | { 13 | readonly string lowercaseA = new('a', 80); 14 | readonly string multibasePrefixed = 'F' + new string('a', 80); 15 | readonly string base45str = new('A', 81); 16 | readonly string emojiStr = string.Concat(Enumerable.Repeat("🚀", 80)); 17 | readonly string allZeroes = new('0', 80); 18 | readonly MemoryStream memoryStream = new(); 19 | static readonly byte[] buffer = new byte[80]; 20 | 21 | [Benchmark] 22 | public byte[] DotNet_Base64() => Convert.FromBase64String(lowercaseA); 23 | 24 | [Benchmark] 25 | public byte[] Base2_Default() => Base2.Default.Decode(allZeroes); 26 | 27 | [Benchmark] 28 | public byte[] Base8_Default() => Base2.Default.Decode(allZeroes); 29 | 30 | [Benchmark] 31 | public byte[] Base16_UpperCase() => Base16.UpperCase.Decode(lowercaseA); 32 | 33 | /// 34 | /// Created to be able to bench StreamHelper 35 | /// The encoding does not matter for benching StreamHelper 36 | /// Base16 is fastest, means less overhead for measuring StreamHelper 37 | /// 38 | /// 39 | /// [IterationSetup] or [IterationCleanup] attributes are not recommended for microbenchmarks, so setup & cleanup are part of the benchmark 40 | /// https://benchmarkdotnet.org/articles/features/setup-and-cleanup.html#sample-introsetupcleanupiteration 41 | /// 42 | [Benchmark] 43 | public void Base16_UpperCase_TextReader() 44 | { 45 | StringReader reader = new(lowercaseA); // No need to dispose, less overhead, StringReader does not leak anything 46 | Base16.UpperCase.Decode(reader, memoryStream); 47 | memoryStream.Position = 0; // Reset output stream, so it does not grow forever, we do not need to read it 48 | } 49 | 50 | [Benchmark] 51 | public byte[] Multibase_Base16_UpperCase() => Multibase.Decode(multibasePrefixed); 52 | 53 | [Benchmark] 54 | public byte[] Multibase_TryDecode_Base16_UpperCase() 55 | { 56 | bool result = Multibase.TryDecode(multibasePrefixed, buffer, out _); 57 | if (!result) 58 | { 59 | throw new InvalidOperationException("Failed to decode"); 60 | } 61 | return buffer; 62 | } 63 | 64 | [Benchmark] 65 | public byte[] Base32_Crockford() => Base32.Crockford.Decode(lowercaseA); 66 | 67 | [Benchmark] 68 | public byte[] Base36_LowerCase() => Base36.LowerCase.Decode(lowercaseA); 69 | 70 | [Benchmark] 71 | public byte[] Base45_Default() => Base45.Default.Decode(base45str); 72 | 73 | [Benchmark] 74 | public byte[] Base58_Bitcoin() => Base58.Bitcoin.Decode(lowercaseA); 75 | 76 | [Benchmark] 77 | public byte[] Base58_Monero() => Base58.Monero.Decode(lowercaseA); 78 | 79 | [Benchmark] 80 | public byte[] Base62_Default() => Base62.Default.Decode(lowercaseA); 81 | 82 | [Benchmark] 83 | public byte[] Base85_Z85() => Base85.Z85.Decode(lowercaseA); 84 | 85 | [Benchmark] 86 | public byte[] Base256Emoji_Default() => Base256Emoji.Default.Decode(emojiStr); 87 | } -------------------------------------------------------------------------------- /benchmark/EncoderBenchmarks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BenchmarkDotNet.Attributes; 3 | using SimpleBase; 4 | 5 | namespace Benchmark; 6 | 7 | [MarkdownExporterAttribute.GitHub] 8 | [MemoryDiagnoser] 9 | public class EncoderBenchmarks 10 | { 11 | readonly byte[] buffer = new byte[64]; 12 | 13 | [Benchmark] 14 | public string DotNet_Base64() => Convert.ToBase64String(buffer); 15 | 16 | [Benchmark] 17 | public string Base2_Default() => Base2.Default.Encode(buffer); 18 | 19 | [Benchmark] 20 | public string Base8_Default() => Base8.Default.Encode(buffer); 21 | 22 | [Benchmark] 23 | public string Base16_UpperCase() => Base16.UpperCase.Encode(buffer); 24 | 25 | [Benchmark] 26 | public string Multibase_Base16_UpperCase() => Multibase.Encode(buffer, MultibaseEncoding.Base16Upper); 27 | 28 | [Benchmark] 29 | public string Base32_CrockfordWithPadding() => Base32.Crockford.Encode(buffer, padding: true); 30 | 31 | [Benchmark] 32 | public string Base36_LowerCase() => Base36.LowerCase.Encode(buffer); 33 | 34 | [Benchmark] 35 | public string Base45_Default() => Base45.Default.Encode(buffer); 36 | 37 | [Benchmark] 38 | public string Base58_Bitcoin() => Base58.Bitcoin.Encode(buffer); 39 | 40 | [Benchmark] 41 | public string Base58_Monero() => Base58.Monero.Encode(buffer); 42 | 43 | [Benchmark] 44 | public string Base62_Default() => Base62.Default.Encode(buffer); 45 | 46 | [Benchmark] 47 | public string Base85_Z85() => Base85.Z85.Encode(buffer); 48 | 49 | [Benchmark] 50 | public string Base256Emoji_Default() => Base256Emoji.Default.Encode(buffer); 51 | } 52 | -------------------------------------------------------------------------------- /benchmark/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Running; 2 | 3 | namespace Benchmark; 4 | 5 | class Program 6 | { 7 | #pragma warning disable IDE0060 // Remove unused parameter 8 | #pragma warning disable IDE0058 // Expression value is never used 9 | static void Main(string[] args) 10 | { 11 | _ = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); 12 | //BenchmarkRunner.Run(); 13 | //BenchmarkRunner.Run(); 14 | } 15 | #pragma warning restore IDE0058 // Expression value is never used 16 | #pragma warning restore IDE0060 // Remove unused parameter 17 | 18 | } 19 | -------------------------------------------------------------------------------- /benchmark/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("benchmark")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("benchmark")] 12 | [assembly: AssemblyCopyright("Copyright © 2014")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("af6d2403-2e6d-48c9-803a-604f5780a9dc")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /benchmark/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Benchmark": { 4 | "commandName": "Project", 5 | "hotReloadEnabled": false 6 | }, 7 | "Benchmark --job short": { 8 | "commandName": "Project", 9 | "commandLineArgs": "--job short" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # SimpleBase 2 | 3 | ## SimpleBase 4 | 5 | [Base16](./simplebase.base16.md) 6 | 7 | [Base16Alphabet](./simplebase.base16alphabet.md) 8 | 9 | [Base256Emoji](./simplebase.base256emoji.md) 10 | 11 | [Base32](./simplebase.base32.md) 12 | 13 | [Base32Alphabet](./simplebase.base32alphabet.md) 14 | 15 | [Base36](./simplebase.base36.md) 16 | 17 | [Base36Alphabet](./simplebase.base36alphabet.md) 18 | 19 | [Base45](./simplebase.base45.md) 20 | 21 | [Base45Alphabet](./simplebase.base45alphabet.md) 22 | 23 | [Base58](./simplebase.base58.md) 24 | 25 | [Base58Alphabet](./simplebase.base58alphabet.md) 26 | 27 | [Base62](./simplebase.base62.md) 28 | 29 | [Base62Alphabet](./simplebase.base62alphabet.md) 30 | 31 | [Base85](./simplebase.base85.md) 32 | 33 | [Base85Alphabet](./simplebase.base85alphabet.md) 34 | 35 | [Base85IPv6](./simplebase.base85ipv6.md) 36 | 37 | [CodingAlphabet](./simplebase.codingalphabet.md) 38 | 39 | [DividingCoder<TAlphabet>](./simplebase.dividingcoder-1.md) 40 | 41 | [IBaseCoder](./simplebase.ibasecoder.md) 42 | 43 | [IBaseStreamCoder](./simplebase.ibasestreamcoder.md) 44 | 45 | [ICodingAlphabet](./simplebase.icodingalphabet.md) 46 | 47 | [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md) 48 | 49 | [INumericBaseCoder](./simplebase.inumericbasecoder.md) 50 | 51 | [MoneroBase58](./simplebase.monerobase58.md) 52 | 53 | [Multibase](./simplebase.multibase.md) 54 | 55 | [MultibaseEncoding](./simplebase.multibaseencoding.md) 56 | 57 | [PaddingPosition](./simplebase.paddingposition.md) 58 | -------------------------------------------------------------------------------- /docs/simplebase.base16alphabet.md: -------------------------------------------------------------------------------- 1 | # Base16Alphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Alphabet representation for Base16 encodings. 6 | 7 | ```csharp 8 | public class Base16Alphabet : CodingAlphabet, ICodingAlphabet 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md) → [Base16Alphabet](./simplebase.base16alphabet.md)
12 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | ## Properties 16 | 17 | ### **UpperCase** 18 | 19 | Gets upper case Base16 alphabet. 20 | 21 | ```csharp 22 | public static Base16Alphabet UpperCase { get; } 23 | ``` 24 | 25 | #### Property Value 26 | 27 | [Base16Alphabet](./simplebase.base16alphabet.md)
28 | 29 | ### **LowerCase** 30 | 31 | Gets lower case Base16 alphabet. 32 | 33 | ```csharp 34 | public static Base16Alphabet LowerCase { get; } 35 | ``` 36 | 37 | #### Property Value 38 | 39 | [Base16Alphabet](./simplebase.base16alphabet.md)
40 | 41 | ### **ModHex** 42 | 43 | Gets ModHex Base16 alphabet, used by Yubico apps. 44 | 45 | ```csharp 46 | public static Base16Alphabet ModHex { get; } 47 | ``` 48 | 49 | #### Property Value 50 | 51 | [Base16Alphabet](./simplebase.base16alphabet.md)
52 | 53 | ### **CaseSensitive** 54 | 55 | Gets a value indicating whether the decoding should be performed in a case sensitive fashion. 56 | The default is false. 57 | 58 | ```csharp 59 | public bool CaseSensitive { get; } 60 | ``` 61 | 62 | #### Property Value 63 | 64 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
65 | 66 | ### **Length** 67 | 68 | Gets the length of the alphabet. 69 | 70 | ```csharp 71 | public int Length { get; } 72 | ``` 73 | 74 | #### Property Value 75 | 76 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
77 | 78 | ### **Value** 79 | 80 | Gets the characters of the alphabet. 81 | 82 | ```csharp 83 | public string Value { get; } 84 | ``` 85 | 86 | #### Property Value 87 | 88 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
89 | 90 | ## Constructors 91 | 92 | ### **Base16Alphabet(String)** 93 | 94 | Initializes a new instance of the [Base16Alphabet](./simplebase.base16alphabet.md) class with 95 | case insensitive semantics. 96 | 97 | ```csharp 98 | public Base16Alphabet(string alphabet) 99 | ``` 100 | 101 | #### Parameters 102 | 103 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
104 | Encoding alphabet. 105 | 106 | ### **Base16Alphabet(String, Boolean)** 107 | 108 | Initializes a new instance of the [Base16Alphabet](./simplebase.base16alphabet.md) class. 109 | 110 | ```csharp 111 | public Base16Alphabet(string alphabet, bool caseSensitive) 112 | ``` 113 | 114 | #### Parameters 115 | 116 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
117 | Encoding alphabet. 118 | 119 | `caseSensitive` [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
120 | If the decoding should be performed case sensitive. 121 | -------------------------------------------------------------------------------- /docs/simplebase.base256emoji.md: -------------------------------------------------------------------------------- 1 | # Base256Emoji 2 | 3 | Namespace: SimpleBase 4 | 5 | Base256 encoding using variable-length emojis. 6 | 7 | ```csharp 8 | public class Base256Emoji : IBaseCoder, INonAllocatingBaseCoder 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [Base256Emoji](./simplebase.base256emoji.md)
12 | Implements [IBaseCoder](./simplebase.ibasecoder.md), [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md) 13 | 14 | **Remarks:** 15 | 16 | The encoded string might consist of one or more UTF-16 17 | code points (char's) for each byte. Be wary of this 18 | when processing the encoded strings. 19 | 20 | ## Properties 21 | 22 | ### **Default** 23 | 24 | Default Base256Emoji instance. 25 | 26 | ```csharp 27 | public static Base256Emoji Default { get; } 28 | ``` 29 | 30 | #### Property Value 31 | 32 | [Base256Emoji](./simplebase.base256emoji.md)
33 | 34 | ## Constructors 35 | 36 | ### **Base256Emoji(String[])** 37 | 38 | Create a new instance of Base256Emoji. 39 | 40 | ```csharp 41 | public Base256Emoji(String[] alphabet) 42 | ``` 43 | 44 | #### Parameters 45 | 46 | `alphabet` [String[]](https://docs.microsoft.com/en-us/dotnet/api/system.string)
47 | An array that contains 256 elements with emoji values corresponding to every byte. 48 | 49 | ## Methods 50 | 51 | ### **Decode(ReadOnlySpan<Char>)** 52 | 53 | ```csharp 54 | public Byte[] Decode(ReadOnlySpan text) 55 | ``` 56 | 57 | #### Parameters 58 | 59 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
60 | 61 | #### Returns 62 | 63 | [Byte[]](https://docs.microsoft.com/en-us/dotnet/api/system.byte)
64 | 65 | ### **Encode(ReadOnlySpan<Byte>)** 66 | 67 | ```csharp 68 | public string Encode(ReadOnlySpan bytes) 69 | ``` 70 | 71 | #### Parameters 72 | 73 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
74 | 75 | #### Returns 76 | 77 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
78 | 79 | ### **GetSafeByteCountForDecoding(ReadOnlySpan<Char>)** 80 | 81 | ```csharp 82 | public int GetSafeByteCountForDecoding(ReadOnlySpan text) 83 | ``` 84 | 85 | #### Parameters 86 | 87 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
88 | 89 | #### Returns 90 | 91 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
92 | 93 | ### **GetSafeCharCountForEncoding(ReadOnlySpan<Byte>)** 94 | 95 | ```csharp 96 | public int GetSafeCharCountForEncoding(ReadOnlySpan buffer) 97 | ``` 98 | 99 | #### Parameters 100 | 101 | `buffer` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
102 | 103 | #### Returns 104 | 105 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
106 | 107 | ### **TryDecode(ReadOnlySpan<Char>, Span<Byte>, Int32&)** 108 | 109 | ```csharp 110 | public bool TryDecode(ReadOnlySpan input, Span output, Int32& bytesWritten) 111 | ``` 112 | 113 | #### Parameters 114 | 115 | `input` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
116 | 117 | `output` [Span<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
118 | 119 | `bytesWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
120 | 121 | #### Returns 122 | 123 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
124 | 125 | ### **TryEncode(ReadOnlySpan<Byte>, Span<Char>, Int32&)** 126 | 127 | ```csharp 128 | public bool TryEncode(ReadOnlySpan input, Span output, Int32& numCharsWritten) 129 | ``` 130 | 131 | #### Parameters 132 | 133 | `input` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
134 | 135 | `output` [Span<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
136 | 137 | `numCharsWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
138 | 139 | #### Returns 140 | 141 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
142 | 143 | **Remarks:** 144 | 145 | numCharsWritten will not correspond to the number of emojis written as one emoji 146 | can be encoded with multiple chars. 147 | -------------------------------------------------------------------------------- /docs/simplebase.base32alphabet.md: -------------------------------------------------------------------------------- 1 | # Base32Alphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Base32 alphabet flavors. 6 | 7 | ```csharp 8 | public class Base32Alphabet : CodingAlphabet, ICodingAlphabet 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md) → [Base32Alphabet](./simplebase.base32alphabet.md)
12 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | ## Properties 16 | 17 | ### **Crockford** 18 | 19 | Gets Crockford alphabet. 20 | 21 | ```csharp 22 | public static Base32Alphabet Crockford { get; } 23 | ``` 24 | 25 | #### Property Value 26 | 27 | [Base32Alphabet](./simplebase.base32alphabet.md)
28 | 29 | ### **Rfc4648** 30 | 31 | Gets RFC4648 alphabet. 32 | 33 | ```csharp 34 | public static Base32Alphabet Rfc4648 { get; } 35 | ``` 36 | 37 | #### Property Value 38 | 39 | [Base32Alphabet](./simplebase.base32alphabet.md)
40 | 41 | ### **ExtendedHex** 42 | 43 | Gets Extended Hex alphabet. 44 | 45 | ```csharp 46 | public static Base32Alphabet ExtendedHex { get; } 47 | ``` 48 | 49 | #### Property Value 50 | 51 | [Base32Alphabet](./simplebase.base32alphabet.md)
52 | 53 | ### **ExtendedHexLower** 54 | 55 | Gets Extended Hex alphabet. 56 | 57 | ```csharp 58 | public static Base32Alphabet ExtendedHexLower { get; } 59 | ``` 60 | 61 | #### Property Value 62 | 63 | [Base32Alphabet](./simplebase.base32alphabet.md)
64 | 65 | ### **ZBase32** 66 | 67 | Gets z-base-32 alphabet. 68 | 69 | ```csharp 70 | public static Base32Alphabet ZBase32 { get; } 71 | ``` 72 | 73 | #### Property Value 74 | 75 | [Base32Alphabet](./simplebase.base32alphabet.md)
76 | 77 | ### **Geohash** 78 | 79 | Gets Geohash alphabet. 80 | 81 | ```csharp 82 | public static Base32Alphabet Geohash { get; } 83 | ``` 84 | 85 | #### Property Value 86 | 87 | [Base32Alphabet](./simplebase.base32alphabet.md)
88 | 89 | ### **FileCoin** 90 | 91 | Gets FileCoin alphabet. 92 | 93 | ```csharp 94 | public static Base32Alphabet FileCoin { get; } 95 | ``` 96 | 97 | #### Property Value 98 | 99 | [Base32Alphabet](./simplebase.base32alphabet.md)
100 | 101 | ### **Base32H** 102 | 103 | Gets Base32H alphabet. 104 | 105 | ```csharp 106 | public static Base32Alphabet Base32H { get; } 107 | ``` 108 | 109 | #### Property Value 110 | 111 | [Base32Alphabet](./simplebase.base32alphabet.md)
112 | 113 | ### **Bech32** 114 | 115 | Gets Bech32 alphabet. 116 | 117 | ```csharp 118 | public static Base32Alphabet Bech32 { get; } 119 | ``` 120 | 121 | #### Property Value 122 | 123 | [Base32Alphabet](./simplebase.base32alphabet.md)
124 | 125 | ### **PaddingChar** 126 | 127 | Gets the padding character used in encoding. 128 | 129 | ```csharp 130 | public char PaddingChar { get; } 131 | ``` 132 | 133 | #### Property Value 134 | 135 | [Char](https://docs.microsoft.com/en-us/dotnet/api/system.char)
136 | 137 | ### **PaddingPosition** 138 | 139 | Gets the position of the padding characters in the encoder output. 140 | 141 | ```csharp 142 | public PaddingPosition PaddingPosition { get; } 143 | ``` 144 | 145 | #### Property Value 146 | 147 | [PaddingPosition](./simplebase.paddingposition.md)
148 | 149 | ### **Length** 150 | 151 | Gets the length of the alphabet. 152 | 153 | ```csharp 154 | public int Length { get; } 155 | ``` 156 | 157 | #### Property Value 158 | 159 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
160 | 161 | ### **Value** 162 | 163 | Gets the characters of the alphabet. 164 | 165 | ```csharp 166 | public string Value { get; } 167 | ``` 168 | 169 | #### Property Value 170 | 171 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
172 | 173 | ## Constructors 174 | 175 | ### **Base32Alphabet(String)** 176 | 177 | Initializes a new instance of the [Base32Alphabet](./simplebase.base32alphabet.md) class. 178 | 179 | ```csharp 180 | public Base32Alphabet(string alphabet) 181 | ``` 182 | 183 | #### Parameters 184 | 185 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
186 | Characters. 187 | 188 | ### **Base32Alphabet(String, Char, PaddingPosition)** 189 | 190 | Initializes a new instance of the [Base32Alphabet](./simplebase.base32alphabet.md) class. 191 | 192 | ```csharp 193 | public Base32Alphabet(string alphabet, char paddingChar, PaddingPosition paddingPosition) 194 | ``` 195 | 196 | #### Parameters 197 | 198 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
199 | Encoding alphabet to use. 200 | 201 | `paddingChar` [Char](https://docs.microsoft.com/en-us/dotnet/api/system.char)
202 | Padding character. 203 | 204 | `paddingPosition` [PaddingPosition](./simplebase.paddingposition.md)
205 | Position of the padding characters in the encoder output. 206 | -------------------------------------------------------------------------------- /docs/simplebase.base36.md: -------------------------------------------------------------------------------- 1 | # Base36 2 | 3 | Namespace: SimpleBase 4 | 5 | Base36 Encoding/Decoding implementation. 6 | 7 | ```csharp 8 | public sealed class Base36 : DividingCoder`1, IBaseCoder, INonAllocatingBaseCoder 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [DividingCoder<Base36Alphabet>](./simplebase.dividingcoder-1.md) → [Base36](./simplebase.base36.md)
12 | Implements [IBaseCoder](./simplebase.ibasecoder.md), [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | **Remarks:** 16 | 17 | Base36 doesn't implement a Stream-based interface because it's not feasible to use 18 | on large buffers. 19 | 20 | ## Properties 21 | 22 | ### **UpperCase** 23 | 24 | Gets the uppercase Base36 encoder. 25 | 26 | ```csharp 27 | public static Base36 UpperCase { get; } 28 | ``` 29 | 30 | #### Property Value 31 | 32 | [Base36](./simplebase.base36.md)
33 | 34 | ### **LowerCase** 35 | 36 | Gets the lowercase Base36 encoder. 37 | 38 | ```csharp 39 | public static Base36 LowerCase { get; } 40 | ``` 41 | 42 | #### Property Value 43 | 44 | [Base36](./simplebase.base36.md)
45 | 46 | ### **Alphabet** 47 | 48 | Gets the encoding alphabet. 49 | 50 | ```csharp 51 | public Base36Alphabet Alphabet { get; } 52 | ``` 53 | 54 | #### Property Value 55 | 56 | [Base36Alphabet](./simplebase.base36alphabet.md)
57 | 58 | ## Constructors 59 | 60 | ### **Base36(Base36Alphabet)** 61 | 62 | Base36 Encoding/Decoding implementation. 63 | 64 | ```csharp 65 | public Base36(Base36Alphabet alphabet) 66 | ``` 67 | 68 | #### Parameters 69 | 70 | `alphabet` [Base36Alphabet](./simplebase.base36alphabet.md)
71 | Alphabet to use. 72 | 73 | **Remarks:** 74 | 75 | Base36 doesn't implement a Stream-based interface because it's not feasible to use 76 | on large buffers. 77 | -------------------------------------------------------------------------------- /docs/simplebase.base36alphabet.md: -------------------------------------------------------------------------------- 1 | # Base36Alphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Base36 encoding/decoding alphabet. 6 | 7 | ```csharp 8 | public class Base36Alphabet : CodingAlphabet, ICodingAlphabet 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md) → [Base36Alphabet](./simplebase.base36alphabet.md)
12 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | ## Properties 16 | 17 | ### **Upper** 18 | 19 | Base36 alphabet with numbers and uppercase letters. 20 | 21 | ```csharp 22 | public static Base36Alphabet Upper { get; } 23 | ``` 24 | 25 | #### Property Value 26 | 27 | [Base36Alphabet](./simplebase.base36alphabet.md)
28 | 29 | ### **Lower** 30 | 31 | Base36 alphabet with numbers and lowercase letters. 32 | 33 | ```csharp 34 | public static Base36Alphabet Lower { get; } 35 | ``` 36 | 37 | #### Property Value 38 | 39 | [Base36Alphabet](./simplebase.base36alphabet.md)
40 | 41 | ### **Length** 42 | 43 | Gets the length of the alphabet. 44 | 45 | ```csharp 46 | public int Length { get; } 47 | ``` 48 | 49 | #### Property Value 50 | 51 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
52 | 53 | ### **Value** 54 | 55 | Gets the characters of the alphabet. 56 | 57 | ```csharp 58 | public string Value { get; } 59 | ``` 60 | 61 | #### Property Value 62 | 63 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
64 | 65 | ## Constructors 66 | 67 | ### **Base36Alphabet(String)** 68 | 69 | Base36 encoding/decoding alphabet. 70 | 71 | ```csharp 72 | public Base36Alphabet(string alphabet) 73 | ``` 74 | 75 | #### Parameters 76 | 77 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
78 | Alphabet to use. 79 | -------------------------------------------------------------------------------- /docs/simplebase.base45.md: -------------------------------------------------------------------------------- 1 | # Base45 2 | 3 | Namespace: SimpleBase 4 | 5 | Base45 encoding/decoding implementation. 6 | 7 | ```csharp 8 | public sealed class Base45 : INonAllocatingBaseCoder, IBaseCoder, IBaseStreamCoder 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [Base45](./simplebase.base45.md)
12 | Implements [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md), [IBaseCoder](./simplebase.ibasecoder.md), [IBaseStreamCoder](./simplebase.ibasestreamcoder.md) 13 | 14 | ## Properties 15 | 16 | ### **Default** 17 | 18 | Gets the default flavor. 19 | 20 | ```csharp 21 | public static Base45 Default { get; } 22 | ``` 23 | 24 | #### Property Value 25 | 26 | [Base45](./simplebase.base45.md)
27 | 28 | ## Constructors 29 | 30 | ### **Base45(Base45Alphabet)** 31 | 32 | Base45 encoding/decoding implementation. 33 | 34 | ```csharp 35 | public Base45(Base45Alphabet alphabet) 36 | ``` 37 | 38 | #### Parameters 39 | 40 | `alphabet` [Base45Alphabet](./simplebase.base45alphabet.md)
41 | Alphabet to use. 42 | 43 | ## Methods 44 | 45 | ### **Decode(ReadOnlySpan<Char>)** 46 | 47 | ```csharp 48 | public Byte[] Decode(ReadOnlySpan text) 49 | ``` 50 | 51 | #### Parameters 52 | 53 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
54 | 55 | #### Returns 56 | 57 | [Byte[]](https://docs.microsoft.com/en-us/dotnet/api/system.byte)
58 | 59 | ### **Encode(ReadOnlySpan<Byte>)** 60 | 61 | ```csharp 62 | public string Encode(ReadOnlySpan bytes) 63 | ``` 64 | 65 | #### Parameters 66 | 67 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
68 | 69 | #### Returns 70 | 71 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
72 | 73 | ### **GetSafeByteCountForDecoding(ReadOnlySpan<Char>)** 74 | 75 | ```csharp 76 | public int GetSafeByteCountForDecoding(ReadOnlySpan text) 77 | ``` 78 | 79 | #### Parameters 80 | 81 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
82 | 83 | #### Returns 84 | 85 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
86 | 87 | ### **GetSafeCharCountForEncoding(ReadOnlySpan<Byte>)** 88 | 89 | ```csharp 90 | public int GetSafeCharCountForEncoding(ReadOnlySpan buffer) 91 | ``` 92 | 93 | #### Parameters 94 | 95 | `buffer` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
96 | 97 | #### Returns 98 | 99 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
100 | 101 | ### **TryDecode(ReadOnlySpan<Char>, Span<Byte>, Int32&)** 102 | 103 | ```csharp 104 | public bool TryDecode(ReadOnlySpan input, Span output, Int32& bytesWritten) 105 | ``` 106 | 107 | #### Parameters 108 | 109 | `input` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
110 | 111 | `output` [Span<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
112 | 113 | `bytesWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
114 | 115 | #### Returns 116 | 117 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
118 | 119 | ### **TryEncode(ReadOnlySpan<Byte>, Span<Char>, Int32&)** 120 | 121 | ```csharp 122 | public bool TryEncode(ReadOnlySpan input, Span output, Int32& numCharsWritten) 123 | ``` 124 | 125 | #### Parameters 126 | 127 | `input` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
128 | 129 | `output` [Span<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
130 | 131 | `numCharsWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
132 | 133 | #### Returns 134 | 135 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
136 | 137 | ### **Encode(Stream, TextWriter)** 138 | 139 | ```csharp 140 | public void Encode(Stream input, TextWriter output) 141 | ``` 142 | 143 | #### Parameters 144 | 145 | `input` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
146 | 147 | `output` [TextWriter](https://docs.microsoft.com/en-us/dotnet/api/system.io.textwriter)
148 | 149 | ### **EncodeAsync(Stream, TextWriter)** 150 | 151 | ```csharp 152 | public Task EncodeAsync(Stream input, TextWriter output) 153 | ``` 154 | 155 | #### Parameters 156 | 157 | `input` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
158 | 159 | `output` [TextWriter](https://docs.microsoft.com/en-us/dotnet/api/system.io.textwriter)
160 | 161 | #### Returns 162 | 163 | [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task)
164 | 165 | ### **Decode(TextReader, Stream)** 166 | 167 | ```csharp 168 | public void Decode(TextReader input, Stream output) 169 | ``` 170 | 171 | #### Parameters 172 | 173 | `input` [TextReader](https://docs.microsoft.com/en-us/dotnet/api/system.io.textreader)
174 | 175 | `output` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
176 | 177 | ### **DecodeAsync(TextReader, Stream)** 178 | 179 | ```csharp 180 | public Task DecodeAsync(TextReader input, Stream output) 181 | ``` 182 | 183 | #### Parameters 184 | 185 | `input` [TextReader](https://docs.microsoft.com/en-us/dotnet/api/system.io.textreader)
186 | 187 | `output` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
188 | 189 | #### Returns 190 | 191 | [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task)
192 | -------------------------------------------------------------------------------- /docs/simplebase.base45alphabet.md: -------------------------------------------------------------------------------- 1 | # Base45Alphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Base45 coding alphabet. 6 | 7 | ```csharp 8 | public class Base45Alphabet : CodingAlphabet, ICodingAlphabet 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md) → [Base45Alphabet](./simplebase.base45alphabet.md)
12 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | ## Properties 16 | 17 | ### **Default** 18 | 19 | Default Base45 alphabet per RFC 9285. 20 | 21 | ```csharp 22 | public static Base45Alphabet Default { get; } 23 | ``` 24 | 25 | #### Property Value 26 | 27 | [Base45Alphabet](./simplebase.base45alphabet.md)
28 | 29 | ### **Length** 30 | 31 | Gets the length of the alphabet. 32 | 33 | ```csharp 34 | public int Length { get; } 35 | ``` 36 | 37 | #### Property Value 38 | 39 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
40 | 41 | ### **Value** 42 | 43 | Gets the characters of the alphabet. 44 | 45 | ```csharp 46 | public string Value { get; } 47 | ``` 48 | 49 | #### Property Value 50 | 51 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
52 | 53 | ## Constructors 54 | 55 | ### **Base45Alphabet(String)** 56 | 57 | Base45 coding alphabet. 58 | 59 | ```csharp 60 | public Base45Alphabet(string alphabet) 61 | ``` 62 | 63 | #### Parameters 64 | 65 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
66 | The characters that build up the Base45 alphabet. 67 | -------------------------------------------------------------------------------- /docs/simplebase.base58alphabet.md: -------------------------------------------------------------------------------- 1 | # Base58Alphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Base58 alphabet. 6 | 7 | ```csharp 8 | public sealed class Base58Alphabet : CodingAlphabet, ICodingAlphabet 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md) → [Base58Alphabet](./simplebase.base58alphabet.md)
12 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | **Remarks:** 16 | 17 | Initializes a new instance of the [Base58Alphabet](./simplebase.base58alphabet.md) class 18 | using a custom alphabet. 19 | 20 | ## Properties 21 | 22 | ### **Bitcoin** 23 | 24 | Gets Bitcoin alphabet. Monero also uses this alphabet but only works with MoneroBase58 encoding. 25 | 26 | ```csharp 27 | public static Base58Alphabet Bitcoin { get; } 28 | ``` 29 | 30 | #### Property Value 31 | 32 | [Base58Alphabet](./simplebase.base58alphabet.md)
33 | 34 | ### **Ripple** 35 | 36 | Gets Base58 alphabet. 37 | 38 | ```csharp 39 | public static Base58Alphabet Ripple { get; } 40 | ``` 41 | 42 | #### Property Value 43 | 44 | [Base58Alphabet](./simplebase.base58alphabet.md)
45 | 46 | ### **Flickr** 47 | 48 | Gets Flickr alphabet. 49 | 50 | ```csharp 51 | public static Base58Alphabet Flickr { get; } 52 | ``` 53 | 54 | #### Property Value 55 | 56 | [Base58Alphabet](./simplebase.base58alphabet.md)
57 | 58 | ### **Length** 59 | 60 | Gets the length of the alphabet. 61 | 62 | ```csharp 63 | public int Length { get; } 64 | ``` 65 | 66 | #### Property Value 67 | 68 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
69 | 70 | ### **Value** 71 | 72 | Gets the characters of the alphabet. 73 | 74 | ```csharp 75 | public string Value { get; } 76 | ``` 77 | 78 | #### Property Value 79 | 80 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
81 | 82 | ## Constructors 83 | 84 | ### **Base58Alphabet(String)** 85 | 86 | Base58 alphabet. 87 | 88 | ```csharp 89 | public Base58Alphabet(string alphabet) 90 | ``` 91 | 92 | #### Parameters 93 | 94 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
95 | Alphabet to use. 96 | 97 | **Remarks:** 98 | 99 | Initializes a new instance of the [Base58Alphabet](./simplebase.base58alphabet.md) class 100 | using a custom alphabet. 101 | -------------------------------------------------------------------------------- /docs/simplebase.base62.md: -------------------------------------------------------------------------------- 1 | # Base62 2 | 3 | Namespace: SimpleBase 4 | 5 | Base62 Encoding/Decoding implementation. 6 | 7 | ```csharp 8 | public sealed class Base62 : DividingCoder`1, IBaseCoder, INonAllocatingBaseCoder 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [DividingCoder<Base62Alphabet>](./simplebase.dividingcoder-1.md) → [Base62](./simplebase.base62.md)
12 | Implements [IBaseCoder](./simplebase.ibasecoder.md), [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | **Remarks:** 16 | 17 | Base62 doesn't implement a Stream-based interface because it's not feasible to use 18 | on large buffers. 19 | 20 | ## Properties 21 | 22 | ### **Default** 23 | 24 | Gets the default flavor. 25 | 26 | ```csharp 27 | public static Base62 Default { get; } 28 | ``` 29 | 30 | #### Property Value 31 | 32 | [Base62](./simplebase.base62.md)
33 | 34 | ### **LowerFirst** 35 | 36 | Gets the alphabet with the lowercase letters first. 37 | 38 | ```csharp 39 | public static Base62 LowerFirst { get; } 40 | ``` 41 | 42 | #### Property Value 43 | 44 | [Base62](./simplebase.base62.md)
45 | 46 | ### **Alphabet** 47 | 48 | Gets the encoding alphabet. 49 | 50 | ```csharp 51 | public Base62Alphabet Alphabet { get; } 52 | ``` 53 | 54 | #### Property Value 55 | 56 | [Base62Alphabet](./simplebase.base62alphabet.md)
57 | 58 | ## Constructors 59 | 60 | ### **Base62(Base62Alphabet)** 61 | 62 | Base62 Encoding/Decoding implementation. 63 | 64 | ```csharp 65 | public Base62(Base62Alphabet alphabet) 66 | ``` 67 | 68 | #### Parameters 69 | 70 | `alphabet` [Base62Alphabet](./simplebase.base62alphabet.md)
71 | Alphabet to use. 72 | 73 | **Remarks:** 74 | 75 | Base62 doesn't implement a Stream-based interface because it's not feasible to use 76 | on large buffers. 77 | -------------------------------------------------------------------------------- /docs/simplebase.base62alphabet.md: -------------------------------------------------------------------------------- 1 | # Base62Alphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Base62 alphabet. 6 | 7 | ```csharp 8 | public sealed class Base62Alphabet : CodingAlphabet, ICodingAlphabet 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md) → [Base62Alphabet](./simplebase.base62alphabet.md)
12 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | **Remarks:** 16 | 17 | Initializes a new instance of the [Base58Alphabet](./simplebase.base58alphabet.md) class 18 | using a custom alphabet. 19 | 20 | ## Properties 21 | 22 | ### **Default** 23 | 24 | Gets the standard, most common alphabet. 25 | 26 | ```csharp 27 | public static Base62Alphabet Default { get; } 28 | ``` 29 | 30 | #### Property Value 31 | 32 | [Base62Alphabet](./simplebase.base62alphabet.md)
33 | 34 | ### **Alternative** 35 | 36 | Gets Alternative alphabet. 37 | 38 | ```csharp 39 | public static Base62Alphabet Alternative { get; } 40 | ``` 41 | 42 | #### Property Value 43 | 44 | [Base62Alphabet](./simplebase.base62alphabet.md)
45 | 46 | ### **Length** 47 | 48 | Gets the length of the alphabet. 49 | 50 | ```csharp 51 | public int Length { get; } 52 | ``` 53 | 54 | #### Property Value 55 | 56 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
57 | 58 | ### **Value** 59 | 60 | Gets the characters of the alphabet. 61 | 62 | ```csharp 63 | public string Value { get; } 64 | ``` 65 | 66 | #### Property Value 67 | 68 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
69 | 70 | ## Constructors 71 | 72 | ### **Base62Alphabet(String)** 73 | 74 | Base62 alphabet. 75 | 76 | ```csharp 77 | public Base62Alphabet(string alphabet) 78 | ``` 79 | 80 | #### Parameters 81 | 82 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
83 | Alphabet to use. 84 | 85 | **Remarks:** 86 | 87 | Initializes a new instance of the [Base58Alphabet](./simplebase.base58alphabet.md) class 88 | using a custom alphabet. 89 | -------------------------------------------------------------------------------- /docs/simplebase.base85alphabet.md: -------------------------------------------------------------------------------- 1 | # Base85Alphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Base85 Alphabet. 6 | 7 | ```csharp 8 | public sealed class Base85Alphabet : CodingAlphabet, ICodingAlphabet 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md) → [Base85Alphabet](./simplebase.base85alphabet.md)
12 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | **Remarks:** 16 | 17 | Initializes a new instance of the [Base85Alphabet](./simplebase.base85alphabet.md) class 18 | using custom settings. 19 | 20 | ## Properties 21 | 22 | ### **Z85** 23 | 24 | Gets ZeroMQ Z85 Alphabet. 25 | 26 | ```csharp 27 | public static Base85Alphabet Z85 { get; } 28 | ``` 29 | 30 | #### Property Value 31 | 32 | [Base85Alphabet](./simplebase.base85alphabet.md)
33 | 34 | ### **Ascii85** 35 | 36 | Gets Adobe Ascii85 Alphabet (each character is directly produced by raw value + 33), 37 | also known as "btoa" encoding. 38 | 39 | ```csharp 40 | public static Base85Alphabet Ascii85 { get; } 41 | ``` 42 | 43 | #### Property Value 44 | 45 | [Base85Alphabet](./simplebase.base85alphabet.md)
46 | 47 | ### **Rfc1924** 48 | 49 | Gets Base85 encoding defined in RFC 1924. 50 | 51 | ```csharp 52 | public static Base85Alphabet Rfc1924 { get; } 53 | ``` 54 | 55 | #### Property Value 56 | 57 | [Base85Alphabet](./simplebase.base85alphabet.md)
58 | 59 | ### **AllZeroShortcut** 60 | 61 | Gets the character to be used for "all zeros". 62 | 63 | ```csharp 64 | public Nullable AllZeroShortcut { get; } 65 | ``` 66 | 67 | #### Property Value 68 | 69 | [Nullable<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1)
70 | 71 | ### **AllSpaceShortcut** 72 | 73 | Gets the character to be used for "all spaces". 74 | 75 | ```csharp 76 | public Nullable AllSpaceShortcut { get; } 77 | ``` 78 | 79 | #### Property Value 80 | 81 | [Nullable<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1)
82 | 83 | ### **HasShortcut** 84 | 85 | Gets a value indicating whether the alphabet uses one of shortcut characters for all spaces 86 | or all zeros. 87 | 88 | ```csharp 89 | public bool HasShortcut { get; } 90 | ``` 91 | 92 | #### Property Value 93 | 94 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
95 | 96 | ### **Length** 97 | 98 | Gets the length of the alphabet. 99 | 100 | ```csharp 101 | public int Length { get; } 102 | ``` 103 | 104 | #### Property Value 105 | 106 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
107 | 108 | ### **Value** 109 | 110 | Gets the characters of the alphabet. 111 | 112 | ```csharp 113 | public string Value { get; } 114 | ``` 115 | 116 | #### Property Value 117 | 118 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
119 | 120 | ## Constructors 121 | 122 | ### **Base85Alphabet(String, Nullable<Char>, Nullable<Char>)** 123 | 124 | Base85 Alphabet. 125 | 126 | ```csharp 127 | public Base85Alphabet(string alphabet, Nullable allZeroShortcut, Nullable allSpaceShortcut) 128 | ``` 129 | 130 | #### Parameters 131 | 132 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
133 | Alphabet to use. 134 | 135 | `allZeroShortcut` [Nullable<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1)
136 | Character to substitute for all zero. 137 | 138 | `allSpaceShortcut` [Nullable<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1)
139 | Character to substitute for all space. 140 | 141 | **Remarks:** 142 | 143 | Initializes a new instance of the [Base85Alphabet](./simplebase.base85alphabet.md) class 144 | using custom settings. 145 | -------------------------------------------------------------------------------- /docs/simplebase.base85ipv6.md: -------------------------------------------------------------------------------- 1 | # Base85IPv6 2 | 3 | Namespace: SimpleBase 4 | 5 | Base85 implementation with additional IPv6 coding functions. 6 | 7 | ```csharp 8 | public class Base85IPv6 : Base85, IBaseCoder, IBaseStreamCoder, INonAllocatingBaseCoder 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [Base85](./simplebase.base85.md) → [Base85IPv6](./simplebase.base85ipv6.md)
12 | Implements [IBaseCoder](./simplebase.ibasecoder.md), [IBaseStreamCoder](./simplebase.ibasestreamcoder.md), [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md)
13 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 14 | 15 | **Remarks:** 16 | 17 | RFC 1924 sucks, arguably because it's a very early proposal in the history of IPv6: 18 | - It contains special chars: It's prone to be confused with other syntactical elements. 19 | It can even cause security issues due to poor escaping, let alone UX problems. 20 | - Length gains are usually marginal: IPv6 uses zero elimination to reduce the address representation. 21 | - Slow. The algorithm is division based, instead of faster bitwise operations. 22 | So, that's why I only included a proof of concept implementation instead of working on optimizing it. 23 | RFC 1924 should die, and this code should only be used to support some obscure standard or code somewhere. 24 | 25 | ## Properties 26 | 27 | ### **Alphabet** 28 | 29 | Gets the encoding alphabet. 30 | 31 | ```csharp 32 | public Base85Alphabet Alphabet { get; } 33 | ``` 34 | 35 | #### Property Value 36 | 37 | [Base85Alphabet](./simplebase.base85alphabet.md)
38 | 39 | ## Constructors 40 | 41 | ### **Base85IPv6(Base85Alphabet)** 42 | 43 | Base85 implementation with additional IPv6 coding functions. 44 | 45 | ```csharp 46 | public Base85IPv6(Base85Alphabet alphabet) 47 | ``` 48 | 49 | #### Parameters 50 | 51 | `alphabet` [Base85Alphabet](./simplebase.base85alphabet.md)
52 | Coding alphabet. 53 | 54 | **Remarks:** 55 | 56 | RFC 1924 sucks, arguably because it's a very early proposal in the history of IPv6: 57 | - It contains special chars: It's prone to be confused with other syntactical elements. 58 | It can even cause security issues due to poor escaping, let alone UX problems. 59 | - Length gains are usually marginal: IPv6 uses zero elimination to reduce the address representation. 60 | - Slow. The algorithm is division based, instead of faster bitwise operations. 61 | So, that's why I only included a proof of concept implementation instead of working on optimizing it. 62 | RFC 1924 should die, and this code should only be used to support some obscure standard or code somewhere. 63 | 64 | ## Methods 65 | 66 | ### **EncodeIPv6(IPAddress)** 67 | 68 | Encode IPv6 address into RFC 1924 Base85 text. 69 | 70 | ```csharp 71 | public string EncodeIPv6(IPAddress ip) 72 | ``` 73 | 74 | #### Parameters 75 | 76 | `ip` IPAddress
77 | IPv6 address. 78 | 79 | #### Returns 80 | 81 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
82 | Encoded text. 83 | 84 | ### **DecodeIPv6(String)** 85 | 86 | Decode an RFC 1924 encoded text into an IPv6 address. 87 | 88 | ```csharp 89 | public IPAddress DecodeIPv6(string text) 90 | ``` 91 | 92 | #### Parameters 93 | 94 | `text` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
95 | Encoded text. 96 | 97 | #### Returns 98 | 99 | IPAddress
100 | Decoded IPv6 address. 101 | 102 | ### **TryDecodeIPv6(String, IPAddress&)** 103 | 104 | Try decoding an RFC 1924 encoded text into an IPv6 address. 105 | 106 | ```csharp 107 | public bool TryDecodeIPv6(string text, IPAddress& ip) 108 | ``` 109 | 110 | #### Parameters 111 | 112 | `text` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
113 | Encoded text. 114 | 115 | `ip` IPAddress&
116 | Resulting IPv6 address. 117 | 118 | #### Returns 119 | 120 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
121 | True if successful, false otherwise. 122 | -------------------------------------------------------------------------------- /docs/simplebase.codingalphabet.md: -------------------------------------------------------------------------------- 1 | # CodingAlphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | A single encoding algorithm can support many different alphabets. 6 | EncodingAlphabet consists of a basis for implementing different 7 | alphabets for different encodings. It's suitable if you want to 8 | implement your own encoding based on the existing base classes. 9 | 10 | ```csharp 11 | public abstract class CodingAlphabet : ICodingAlphabet 12 | ``` 13 | 14 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [CodingAlphabet](./simplebase.codingalphabet.md)
15 | Implements [ICodingAlphabet](./simplebase.icodingalphabet.md)
16 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute), [NullableAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullableattribute) 17 | 18 | ## Properties 19 | 20 | ### **Length** 21 | 22 | Gets the length of the alphabet. 23 | 24 | ```csharp 25 | public int Length { get; private set; } 26 | ``` 27 | 28 | #### Property Value 29 | 30 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
31 | 32 | ### **Value** 33 | 34 | Gets the characters of the alphabet. 35 | 36 | ```csharp 37 | public string Value { get; private set; } 38 | ``` 39 | 40 | #### Property Value 41 | 42 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
43 | 44 | ## Constructors 45 | 46 | ### **CodingAlphabet(Int32, String)** 47 | 48 | Initializes a new instance of the [CodingAlphabet](./simplebase.codingalphabet.md) class. 49 | 50 | ```csharp 51 | public CodingAlphabet(int length, string alphabet) 52 | ``` 53 | 54 | #### Parameters 55 | 56 | `length` [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
57 | Length of the alphabe. 58 | 59 | `alphabet` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
60 | Alphabet character. 61 | 62 | ## Methods 63 | 64 | ### **InvalidCharacter(Char)** 65 | 66 | Generates a standard invalid character exception for alphabets. 67 | 68 | ```csharp 69 | public static Exception InvalidCharacter(char c) 70 | ``` 71 | 72 | #### Parameters 73 | 74 | `c` [Char](https://docs.microsoft.com/en-us/dotnet/api/system.char)
75 | Characters. 76 | 77 | #### Returns 78 | 79 | [Exception](https://docs.microsoft.com/en-us/dotnet/api/system.exception)
80 | Exception to be thrown. 81 | 82 | **Remarks:** 83 | 84 | The reason this is not a throwing method itself is 85 | that the compiler has no way of knowing whether the execution 86 | will end after the method call and can incorrectly assume 87 | reachable code. 88 | 89 | ### **ToString()** 90 | 91 | Get the string representation of the alphabet. 92 | 93 | ```csharp 94 | public string ToString() 95 | ``` 96 | 97 | #### Returns 98 | 99 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
100 | The characters of the encoding alphabet. 101 | 102 | ### **GetHashCode()** 103 | 104 | ```csharp 105 | public int GetHashCode() 106 | ``` 107 | 108 | #### Returns 109 | 110 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
111 | 112 | ### **Map(Char, Int32)** 113 | 114 | Map a character to a value. 115 | 116 | ```csharp 117 | protected void Map(char c, int value) 118 | ``` 119 | 120 | #### Parameters 121 | 122 | `c` [Char](https://docs.microsoft.com/en-us/dotnet/api/system.char)
123 | Characters. 124 | 125 | `value` [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
126 | Corresponding value. 127 | -------------------------------------------------------------------------------- /docs/simplebase.dividingcoder-1.md: -------------------------------------------------------------------------------- 1 | # DividingCoder<TAlphabet> 2 | 3 | Namespace: SimpleBase 4 | 5 | Generic dividing Encoding/Decoding implementation to be used by other dividing encoders. 6 | 7 | ```csharp 8 | public abstract class DividingCoder : IBaseCoder, INonAllocatingBaseCoder 9 | ``` 10 | 11 | #### Type Parameters 12 | 13 | `TAlphabet`
14 | 15 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [DividingCoder<TAlphabet>](./simplebase.dividingcoder-1.md)
16 | Implements [IBaseCoder](./simplebase.ibasecoder.md), [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md) 17 | 18 | **Remarks:** 19 | 20 | This isn't used by Base58 because it handles zero-prefixes differently than other encodings. 21 | 22 | ## Properties 23 | 24 | ### **Alphabet** 25 | 26 | Gets the encoding alphabet. 27 | 28 | ```csharp 29 | public TAlphabet Alphabet { get; } 30 | ``` 31 | 32 | #### Property Value 33 | 34 | TAlphabet
35 | 36 | ## Constructors 37 | 38 | ### **DividingCoder(TAlphabet)** 39 | 40 | Creates a new instance of DividingCoder with a given alphabet. 41 | 42 | ```csharp 43 | public DividingCoder(TAlphabet alphabet) 44 | ``` 45 | 46 | #### Parameters 47 | 48 | `alphabet` TAlphabet
49 | Alphabet to use. The length of alphabet is used as a divisor. 50 | 51 | ## Methods 52 | 53 | ### **GetSafeByteCountForDecoding(ReadOnlySpan<Char>)** 54 | 55 | ```csharp 56 | public int GetSafeByteCountForDecoding(ReadOnlySpan text) 57 | ``` 58 | 59 | #### Parameters 60 | 61 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
62 | 63 | #### Returns 64 | 65 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
66 | 67 | ### **GetSafeCharCountForEncoding(ReadOnlySpan<Byte>)** 68 | 69 | ```csharp 70 | public int GetSafeCharCountForEncoding(ReadOnlySpan bytes) 71 | ``` 72 | 73 | #### Parameters 74 | 75 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
76 | 77 | #### Returns 78 | 79 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
80 | 81 | ### **Encode(ReadOnlySpan<Byte>)** 82 | 83 | Encode to given base 84 | 85 | ```csharp 86 | public string Encode(ReadOnlySpan bytes) 87 | ``` 88 | 89 | #### Parameters 90 | 91 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
92 | Bytes to encode. 93 | 94 | #### Returns 95 | 96 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
97 | Encoded string. 98 | 99 | ### **Decode(ReadOnlySpan<Char>)** 100 | 101 | Decode from a given base 102 | 103 | ```csharp 104 | public Byte[] Decode(ReadOnlySpan text) 105 | ``` 106 | 107 | #### Parameters 108 | 109 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
110 | Encoded text. 111 | 112 | #### Returns 113 | 114 | [Byte[]](https://docs.microsoft.com/en-us/dotnet/api/system.byte)
115 | Decoded bytes. 116 | 117 | ### **TryEncode(ReadOnlySpan<Byte>, Span<Char>, Int32&)** 118 | 119 | ```csharp 120 | public bool TryEncode(ReadOnlySpan input, Span output, Int32& numCharsWritten) 121 | ``` 122 | 123 | #### Parameters 124 | 125 | `input` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
126 | 127 | `output` [Span<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
128 | 129 | `numCharsWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
130 | 131 | #### Returns 132 | 133 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
134 | 135 | ### **TryDecode(ReadOnlySpan<Char>, Span<Byte>, Int32&)** 136 | 137 | ```csharp 138 | public bool TryDecode(ReadOnlySpan input, Span output, Int32& bytesWritten) 139 | ``` 140 | 141 | #### Parameters 142 | 143 | `input` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
144 | 145 | `output` [Span<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
146 | 147 | `bytesWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
148 | 149 | #### Returns 150 | 151 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
152 | -------------------------------------------------------------------------------- /docs/simplebase.ibasecoder.md: -------------------------------------------------------------------------------- 1 | # IBaseCoder 2 | 3 | Namespace: SimpleBase 4 | 5 | Basic encoding functionality. 6 | 7 | ```csharp 8 | public interface IBaseCoder 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### **Encode(ReadOnlySpan<Byte>)** 14 | 15 | Encode a buffer to base-encoded representation. 16 | 17 | ```csharp 18 | string Encode(ReadOnlySpan bytes) 19 | ``` 20 | 21 | #### Parameters 22 | 23 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
24 | Bytes to encode. 25 | 26 | #### Returns 27 | 28 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
29 | Base16 string. 30 | 31 | ### **Decode(ReadOnlySpan<Char>)** 32 | 33 | Decode base-encoded text into bytes. 34 | 35 | ```csharp 36 | Byte[] Decode(ReadOnlySpan text) 37 | ``` 38 | 39 | #### Parameters 40 | 41 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
42 | Base16 text. 43 | 44 | #### Returns 45 | 46 | [Byte[]](https://docs.microsoft.com/en-us/dotnet/api/system.byte)
47 | Decoded bytes. 48 | -------------------------------------------------------------------------------- /docs/simplebase.ibasestreamcoder.md: -------------------------------------------------------------------------------- 1 | # IBaseStreamCoder 2 | 3 | Namespace: SimpleBase 4 | 5 | Stream-based encoding functionality. 6 | 7 | ```csharp 8 | public interface IBaseStreamCoder 9 | ``` 10 | 11 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute) 12 | 13 | ## Methods 14 | 15 | ### **Encode(Stream, TextWriter)** 16 | 17 | Encodes stream of bytes into base-encoded text. 18 | 19 | ```csharp 20 | void Encode(Stream input, TextWriter output) 21 | ``` 22 | 23 | #### Parameters 24 | 25 | `input` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
26 | Stream that provides bytes to be encoded. 27 | 28 | `output` [TextWriter](https://docs.microsoft.com/en-us/dotnet/api/system.io.textwriter)
29 | Stream that the encoded text is written to. 30 | 31 | ### **EncodeAsync(Stream, TextWriter)** 32 | 33 | Encodes stream of bytes into base-encoded text. 34 | 35 | ```csharp 36 | Task EncodeAsync(Stream input, TextWriter output) 37 | ``` 38 | 39 | #### Parameters 40 | 41 | `input` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
42 | Stream that provides bytes to be encoded. 43 | 44 | `output` [TextWriter](https://docs.microsoft.com/en-us/dotnet/api/system.io.textwriter)
45 | Stream that the encoded text is written to. 46 | 47 | #### Returns 48 | 49 | [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task)
50 | A [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) representing the asynchronous operation. 51 | 52 | ### **Decode(TextReader, Stream)** 53 | 54 | Decode base-encoded text through streams. Stream based variant tries to consume 55 | as little memory as possible, and relies of .NET's own underlying buffering mechanisms, 56 | contrary to their buffer-based versions. 57 | 58 | ```csharp 59 | void Decode(TextReader input, Stream output) 60 | ``` 61 | 62 | #### Parameters 63 | 64 | `input` [TextReader](https://docs.microsoft.com/en-us/dotnet/api/system.io.textreader)
65 | Stream that the encoded bytes would be read from. 66 | 67 | `output` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
68 | Stream where decoded bytes will be written to. 69 | 70 | ### **DecodeAsync(TextReader, Stream)** 71 | 72 | Decode base-encoded text through streams. Stream based variant tries to consume 73 | as little memory as possible, and relies of .NET's own underlying buffering mechanisms, 74 | contrary to their buffer-based versions. 75 | 76 | ```csharp 77 | Task DecodeAsync(TextReader input, Stream output) 78 | ``` 79 | 80 | #### Parameters 81 | 82 | `input` [TextReader](https://docs.microsoft.com/en-us/dotnet/api/system.io.textreader)
83 | Stream that the encoded bytes would be read from. 84 | 85 | `output` [Stream](https://docs.microsoft.com/en-us/dotnet/api/system.io.stream)
86 | Stream where decoded bytes will be written to. 87 | 88 | #### Returns 89 | 90 | [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task)
91 | A [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) representing the asynchronous operation. 92 | -------------------------------------------------------------------------------- /docs/simplebase.icodingalphabet.md: -------------------------------------------------------------------------------- 1 | # ICodingAlphabet 2 | 3 | Namespace: SimpleBase 4 | 5 | Defines basic encoding alphabet. 6 | 7 | ```csharp 8 | public interface ICodingAlphabet 9 | ``` 10 | 11 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute) 12 | 13 | ## Properties 14 | 15 | ### **Value** 16 | 17 | Gets the characters in the alphabet. 18 | 19 | ```csharp 20 | public abstract string Value { get; } 21 | ``` 22 | 23 | #### Property Value 24 | 25 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
26 | 27 | ### **Length** 28 | 29 | Gets the length of the alphabet. 30 | 31 | ```csharp 32 | public abstract int Length { get; } 33 | ``` 34 | 35 | #### Property Value 36 | 37 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
38 | -------------------------------------------------------------------------------- /docs/simplebase.inonallocatingbasecoder.md: -------------------------------------------------------------------------------- 1 | # INonAllocatingBaseCoder 2 | 3 | Namespace: SimpleBase 4 | 5 | Efficient encoding functionality using pre-allocated memory buffers by the callers. 6 | 7 | ```csharp 8 | public interface INonAllocatingBaseCoder 9 | ``` 10 | 11 | ## Methods 12 | 13 | ### **TryEncode(ReadOnlySpan<Byte>, Span<Char>, Int32&)** 14 | 15 | Encode a buffer into a base-encoded representation using pre-allocated buffers. 16 | 17 | ```csharp 18 | bool TryEncode(ReadOnlySpan input, Span output, Int32& numCharsWritten) 19 | ``` 20 | 21 | #### Parameters 22 | 23 | `input` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
24 | Bytes to encode. 25 | 26 | `output` [Span<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
27 | Output buffer. 28 | 29 | `numCharsWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
30 | Actual number of characters written to the output. 31 | 32 | #### Returns 33 | 34 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
35 | Whether encoding was successful or not. If false, `numCharsWritten` 36 | will be zero and the content of `output` will be undefined. 37 | 38 | ### **TryDecode(ReadOnlySpan<Char>, Span<Byte>, Int32&)** 39 | 40 | Decode an encoded character buffer into a pre-allocated output buffer. 41 | 42 | ```csharp 43 | bool TryDecode(ReadOnlySpan input, Span output, Int32& bytesWritten) 44 | ``` 45 | 46 | #### Parameters 47 | 48 | `input` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
49 | Encoded text. 50 | 51 | `output` [Span<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
52 | Output buffer. 53 | 54 | `bytesWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
55 | Actual number of bytes written to the output. 56 | 57 | #### Returns 58 | 59 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
60 | Whether decoding was successful. If false, the value of `bytesWritten` 61 | will be zero and the content of `output` will be undefined. 62 | 63 | ### **GetSafeByteCountForDecoding(ReadOnlySpan<Char>)** 64 | 65 | Gets a safe estimation about how many bytes decoding will take without performing 66 | the actual decoding operation. The estimation can be slightly larger than the actual 67 | output size. 68 | 69 | ```csharp 70 | int GetSafeByteCountForDecoding(ReadOnlySpan text) 71 | ``` 72 | 73 | #### Parameters 74 | 75 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
76 | Text to be decoded. 77 | 78 | #### Returns 79 | 80 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
81 | Number of estimated bytes, or zero if the input length is invalid. 82 | 83 | ### **GetSafeCharCountForEncoding(ReadOnlySpan<Byte>)** 84 | 85 | Gets a safe estimation about how many characters encoding a buffer will take without 86 | performing the actual encoding operation. The estimation can be slightly larger than the 87 | actual output size. 88 | 89 | ```csharp 90 | int GetSafeCharCountForEncoding(ReadOnlySpan buffer) 91 | ``` 92 | 93 | #### Parameters 94 | 95 | `buffer` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
96 | Bytes to be encoded. 97 | 98 | #### Returns 99 | 100 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
101 | Number of estimated characters, or zero if the input length is invalid. 102 | -------------------------------------------------------------------------------- /docs/simplebase.inumericbasecoder.md: -------------------------------------------------------------------------------- 1 | # INumericBaseCoder 2 | 3 | Namespace: SimpleBase 4 | 5 | Number-based coding functions. 6 | 7 | ```csharp 8 | public interface INumericBaseCoder 9 | ``` 10 | 11 | Attributes [NullableContextAttribute](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.nullablecontextattribute) 12 | 13 | ## Methods 14 | 15 | ### **Encode(Int64)** 16 | 17 | Encode the given number. 18 | 19 | ```csharp 20 | string Encode(long number) 21 | ``` 22 | 23 | #### Parameters 24 | 25 | `number` [Int64](https://docs.microsoft.com/en-us/dotnet/api/system.int64)
26 | Number to encode. 27 | 28 | #### Returns 29 | 30 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
31 | Encoded string. 32 | 33 | #### Exceptions 34 | 35 | [ArgumentOutOfRangeException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception)
36 | If number is negative. 37 | 38 | **Remarks:** 39 | 40 | Negative numbers are not supported. 41 | 42 | ### **Encode(UInt64)** 43 | 44 | Encode the given number. 45 | 46 | ```csharp 47 | string Encode(ulong number) 48 | ``` 49 | 50 | #### Parameters 51 | 52 | `number` [UInt64](https://docs.microsoft.com/en-us/dotnet/api/system.uint64)
53 | Number to encode. 54 | 55 | #### Returns 56 | 57 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
58 | Encoded string. 59 | 60 | ### **DecodeInt64(String)** 61 | 62 | Decode text to a number. 63 | 64 | ```csharp 65 | long DecodeInt64(string text) 66 | ``` 67 | 68 | #### Parameters 69 | 70 | `text` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
71 | Text to decode. 72 | 73 | #### Returns 74 | 75 | [Int64](https://docs.microsoft.com/en-us/dotnet/api/system.int64)
76 | Decoded number. 77 | 78 | #### Exceptions 79 | 80 | [InvalidOperationException](https://docs.microsoft.com/en-us/dotnet/api/system.invalidoperationexception)
81 | If the decoded number is larger to fit in a variable or is negative. 82 | 83 | ### **DecodeUInt64(String)** 84 | 85 | Decode text to a number. 86 | 87 | ```csharp 88 | ulong DecodeUInt64(string text) 89 | ``` 90 | 91 | #### Parameters 92 | 93 | `text` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
94 | Text to decode. 95 | 96 | #### Returns 97 | 98 | [UInt64](https://docs.microsoft.com/en-us/dotnet/api/system.uint64)
99 | Decoded number. 100 | 101 | #### Exceptions 102 | 103 | [InvalidOperationException](https://docs.microsoft.com/en-us/dotnet/api/system.invalidoperationexception)
104 | If the decoded number is larger to fit in a variable. 105 | 106 | ### **TryDecodeUInt64(String, UInt64&)** 107 | 108 | Try to decode text into a number without throwing an exception. 109 | 110 | ```csharp 111 | bool TryDecodeUInt64(string text, UInt64& number) 112 | ``` 113 | 114 | #### Parameters 115 | 116 | `text` [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
117 | Input text. 118 | 119 | `number` [UInt64&](https://docs.microsoft.com/en-us/dotnet/api/system.uint64&)
120 | Output number. 121 | 122 | #### Returns 123 | 124 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
125 | True if successful, false otherwise. 126 | -------------------------------------------------------------------------------- /docs/simplebase.monerobase58.md: -------------------------------------------------------------------------------- 1 | # MoneroBase58 2 | 3 | Namespace: SimpleBase 4 | 5 | Monero variant of Base58 Encoding/Decoding algorithm. Differently from other Base58 implementations, 6 | Monero encodes using 8-byte blocks and converts them into 11-byte blocks instead of going byte-by-byte. 7 | This makes Monero a bit less algorihmically complex. If the block size is smaller than 11 bytes, the 8 | rest is padded with encoded zeroes ("1" on Monero Base58 alphabet). 9 | 10 | ```csharp 11 | public sealed class MoneroBase58 : IBaseCoder, INonAllocatingBaseCoder 12 | ``` 13 | 14 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [MoneroBase58](./simplebase.monerobase58.md)
15 | Implements [IBaseCoder](./simplebase.ibasecoder.md), [INonAllocatingBaseCoder](./simplebase.inonallocatingbasecoder.md) 16 | 17 | ## Properties 18 | 19 | ### **Alphabet** 20 | 21 | Gets the encoding alphabet. 22 | 23 | ```csharp 24 | public Base58Alphabet Alphabet { get; } 25 | ``` 26 | 27 | #### Property Value 28 | 29 | [Base58Alphabet](./simplebase.base58alphabet.md)
30 | 31 | ### **ZeroChar** 32 | 33 | Gets the character for zero. 34 | 35 | ```csharp 36 | public char ZeroChar { get; } 37 | ``` 38 | 39 | #### Property Value 40 | 41 | [Char](https://docs.microsoft.com/en-us/dotnet/api/system.char)
42 | 43 | ## Constructors 44 | 45 | ### **MoneroBase58(Base58Alphabet)** 46 | 47 | Monero variant of Base58 Encoding/Decoding algorithm. Differently from other Base58 implementations, 48 | Monero encodes using 8-byte blocks and converts them into 11-byte blocks instead of going byte-by-byte. 49 | This makes Monero a bit less algorihmically complex. If the block size is smaller than 11 bytes, the 50 | rest is padded with encoded zeroes ("1" on Monero Base58 alphabet). 51 | 52 | ```csharp 53 | public MoneroBase58(Base58Alphabet alphabet) 54 | ``` 55 | 56 | #### Parameters 57 | 58 | `alphabet` [Base58Alphabet](./simplebase.base58alphabet.md)
59 | An optional custom alphabet to use. By default, monero uses Bitcoin alphabet. 60 | 61 | ### **MoneroBase58()** 62 | 63 | Initializes a new instance of the [MoneroBase58](./simplebase.monerobase58.md) class 64 | 65 | ```csharp 66 | public MoneroBase58() 67 | ``` 68 | 69 | ## Methods 70 | 71 | ### **GetSafeByteCountForDecoding(ReadOnlySpan<Char>)** 72 | 73 | ```csharp 74 | public int GetSafeByteCountForDecoding(ReadOnlySpan text) 75 | ``` 76 | 77 | #### Parameters 78 | 79 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
80 | 81 | #### Returns 82 | 83 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
84 | 85 | ### **GetSafeCharCountForEncoding(ReadOnlySpan<Byte>)** 86 | 87 | ```csharp 88 | public int GetSafeCharCountForEncoding(ReadOnlySpan bytes) 89 | ``` 90 | 91 | #### Parameters 92 | 93 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
94 | 95 | #### Returns 96 | 97 | [Int32](https://docs.microsoft.com/en-us/dotnet/api/system.int32)
98 | 99 | ### **Encode(ReadOnlySpan<Byte>)** 100 | 101 | Encode to Base58 representation. 102 | 103 | ```csharp 104 | public string Encode(ReadOnlySpan bytes) 105 | ``` 106 | 107 | #### Parameters 108 | 109 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
110 | Bytes to encode. 111 | 112 | #### Returns 113 | 114 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
115 | Encoded string. 116 | 117 | ### **Decode(ReadOnlySpan<Char>)** 118 | 119 | Decode a Base58 representation. 120 | 121 | ```csharp 122 | public Byte[] Decode(ReadOnlySpan text) 123 | ``` 124 | 125 | #### Parameters 126 | 127 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
128 | Base58 encoded text. 129 | 130 | #### Returns 131 | 132 | [Byte[]](https://docs.microsoft.com/en-us/dotnet/api/system.byte)
133 | Decoded bytes. 134 | 135 | ### **TryEncode(ReadOnlySpan<Byte>, Span<Char>, Int32&)** 136 | 137 | ```csharp 138 | public bool TryEncode(ReadOnlySpan input, Span output, Int32& numCharsWritten) 139 | ``` 140 | 141 | #### Parameters 142 | 143 | `input` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
144 | 145 | `output` [Span<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
146 | 147 | `numCharsWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
148 | 149 | #### Returns 150 | 151 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
152 | 153 | ### **TryDecode(ReadOnlySpan<Char>, Span<Byte>, Int32&)** 154 | 155 | ```csharp 156 | public bool TryDecode(ReadOnlySpan input, Span output, Int32& bytesWritten) 157 | ``` 158 | 159 | #### Parameters 160 | 161 | `input` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
162 | 163 | `output` [Span<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
164 | 165 | `bytesWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
166 | 167 | #### Returns 168 | 169 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
170 | -------------------------------------------------------------------------------- /docs/simplebase.multibase.md: -------------------------------------------------------------------------------- 1 | # Multibase 2 | 3 | Namespace: SimpleBase 4 | 5 | Multibase encoding and decoding. 6 | 7 | ```csharp 8 | public static class Multibase 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [Multibase](./simplebase.multibase.md) 12 | 13 | ## Methods 14 | 15 | ### **Decode(ReadOnlySpan<Char>)** 16 | 17 | Decodes a multibase encoded string. 18 | 19 | ```csharp 20 | public static Byte[] Decode(ReadOnlySpan text) 21 | ``` 22 | 23 | #### Parameters 24 | 25 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
26 | Input text. 27 | 28 | #### Returns 29 | 30 | [Byte[]](https://docs.microsoft.com/en-us/dotnet/api/system.byte)
31 | Decoded bytes. 32 | 33 | #### Exceptions 34 | 35 | [ArgumentException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentexception)
36 | If the text is empty or has unsupported encoding. 37 | 38 | ### **TryDecode(ReadOnlySpan<Char>, Span<Byte>, Int32&)** 39 | 40 | Tries to decode a multibase encoded string into a span of bytes. 41 | 42 | ```csharp 43 | public static bool TryDecode(ReadOnlySpan text, Span bytes, Int32& bytesWritten) 44 | ``` 45 | 46 | #### Parameters 47 | 48 | `text` [ReadOnlySpan<Char>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
49 | Input text. 50 | 51 | `bytes` [Span<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.span-1)
52 | Output span. 53 | 54 | `bytesWritten` [Int32&](https://docs.microsoft.com/en-us/dotnet/api/system.int32&)
55 | Number of bytes written to the output span. 56 | 57 | #### Returns 58 | 59 | [Boolean](https://docs.microsoft.com/en-us/dotnet/api/system.boolean)
60 | True if successful, false otherwise. 61 | 62 | ### **Encode(ReadOnlySpan<Byte>, MultibaseEncoding)** 63 | 64 | Encodes a byte array into a multibase encoded string with given encoding. 65 | 66 | ```csharp 67 | public static string Encode(ReadOnlySpan bytes, MultibaseEncoding encoding) 68 | ``` 69 | 70 | #### Parameters 71 | 72 | `bytes` [ReadOnlySpan<Byte>](https://docs.microsoft.com/en-us/dotnet/api/system.readonlyspan-1)
73 | 74 | `encoding` [MultibaseEncoding](./simplebase.multibaseencoding.md)
75 | 76 | #### Returns 77 | 78 | [String](https://docs.microsoft.com/en-us/dotnet/api/system.string)
79 | 80 | #### Exceptions 81 | 82 | [NotImplementedException](https://docs.microsoft.com/en-us/dotnet/api/system.notimplementedexception)
83 | -------------------------------------------------------------------------------- /docs/simplebase.multibaseencoding.md: -------------------------------------------------------------------------------- 1 | # MultibaseEncoding 2 | 3 | Namespace: SimpleBase 4 | 5 | Currently supported Multibase encodings. 6 | 7 | ```csharp 8 | public enum MultibaseEncoding 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [ValueType](https://docs.microsoft.com/en-us/dotnet/api/system.valuetype) → [Enum](https://docs.microsoft.com/en-us/dotnet/api/system.enum) → [MultibaseEncoding](./simplebase.multibaseencoding.md)
12 | Implements [IComparable](https://docs.microsoft.com/en-us/dotnet/api/system.icomparable), [ISpanFormattable](https://docs.microsoft.com/en-us/dotnet/api/system.ispanformattable), [IFormattable](https://docs.microsoft.com/en-us/dotnet/api/system.iformattable), [IConvertible](https://docs.microsoft.com/en-us/dotnet/api/system.iconvertible) 13 | 14 | ## Fields 15 | 16 | | Name | Value | Description | 17 | | --- | --: | --- | 18 | | Base16Lower | 102 | | 19 | | Base16Upper | 70 | | 20 | | Base32Lower | 98 | | 21 | | Base32Upper | 66 | | 22 | | Base58Bitcoin | 122 | | 23 | | Base64 | 109 | | 24 | | Base64Pad | 77 | | 25 | | Base64Url | 117 | | 26 | | Base64UrlPad | 85 | | 27 | | Base32Z | 104 | | 28 | | Base36Lower | 107 | | 29 | | Base36Upper | 75 | | 30 | | Base45 | 82 | | 31 | | Base58Flickr | 90 | | 32 | | Base32HexLower | 118 | | 33 | | Base32HexUpper | 86 | | 34 | | Base256Emoji | 55357 | | 35 | -------------------------------------------------------------------------------- /docs/simplebase.paddingposition.md: -------------------------------------------------------------------------------- 1 | # PaddingPosition 2 | 3 | Namespace: SimpleBase 4 | 5 | Position of the padding in an encoder output. 6 | 7 | ```csharp 8 | public enum PaddingPosition 9 | ``` 10 | 11 | Inheritance [Object](https://docs.microsoft.com/en-us/dotnet/api/system.object) → [ValueType](https://docs.microsoft.com/en-us/dotnet/api/system.valuetype) → [Enum](https://docs.microsoft.com/en-us/dotnet/api/system.enum) → [PaddingPosition](./simplebase.paddingposition.md)
12 | Implements [IComparable](https://docs.microsoft.com/en-us/dotnet/api/system.icomparable), [ISpanFormattable](https://docs.microsoft.com/en-us/dotnet/api/system.ispanformattable), [IFormattable](https://docs.microsoft.com/en-us/dotnet/api/system.iformattable), [IConvertible](https://docs.microsoft.com/en-us/dotnet/api/system.iconvertible) 13 | 14 | ## Fields 15 | 16 | | Name | Value | Description | 17 | | --- | --: | --- | 18 | | Start | 0 | Padding appears at the start of the encoded buffer. | 19 | | End | 1 | Padding appears at the end of the buffer. | 20 | -------------------------------------------------------------------------------- /generate_docs.ps1: -------------------------------------------------------------------------------- 1 | if (!(Get-Command xmldoc2md)) { 2 | dotnet tool install -g XMLDoc2Markdown 3 | } 4 | 5 | dotnet build src 6 | xmldoc2md ./src/bin/Debug/net8.0/SimpleBase.dll -o docs -------------------------------------------------------------------------------- /pack.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | dotnet pack src -c Release -o . 3 | -------------------------------------------------------------------------------- /pack.sh: -------------------------------------------------------------------------------- 1 | dotnet pack src -c Release -o . 2 | -------------------------------------------------------------------------------- /push.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | dotnet nuget push %1 --source https://api.nuget.org/v3/index.json 3 | dotnet nuget push %1 --source "GitHub" -------------------------------------------------------------------------------- /push.sh: -------------------------------------------------------------------------------- 1 | nuget push $1 -Source https://api.nuget.org/v3/index.json 2 | nuget push $1 -Source GitHub -------------------------------------------------------------------------------- /src/AliasedBase32Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System.Collections.Generic; 7 | 8 | namespace SimpleBase; 9 | 10 | sealed class AliasedBase32Alphabet : Base32Alphabet 11 | { 12 | public AliasedBase32Alphabet(string alphabet, IEnumerable map) 13 | : base(alphabet) 14 | { 15 | setupMap(map); 16 | } 17 | 18 | public AliasedBase32Alphabet( 19 | string alphabet, 20 | char paddingChar, 21 | PaddingPosition paddingPosition, 22 | IEnumerable map) 23 | : base(alphabet, paddingChar, paddingPosition) 24 | { 25 | setupMap(map); 26 | } 27 | 28 | void setupMap(IEnumerable map) 29 | { 30 | foreach (var (from, to) in map) 31 | { 32 | mapAlternate(from, to); 33 | } 34 | } 35 | 36 | void mapAlternate(char source, char destination) 37 | { 38 | int result = ReverseLookupTable[destination] - 1; 39 | Map(source, result); 40 | Map(char.ToLowerInvariant(source), result); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Base10.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base10 encoder. 12 | /// 13 | /// Alphabet to use. 14 | public class Base10(Base10Alphabet alphabet): DividingCoder(alphabet) 15 | { 16 | /// 17 | /// Default Base10 implementation. 18 | /// 19 | static readonly Lazy @default = new(() => new Base10(Base10Alphabet.Default)); 20 | 21 | /// 22 | /// Default Base10 implementation. 23 | /// 24 | public static Base10 Default => @default.Value; 25 | } 26 | -------------------------------------------------------------------------------- /src/Base10Alphabet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SimpleBase; 4 | 5 | /// 6 | /// Base 10 encoding alphabet. 7 | /// 8 | /// Characters to use for encoding. 9 | public class Base10Alphabet(string alphabet) : CodingAlphabet(10, alphabet) 10 | { 11 | /// 12 | /// Default Base10 alphabet. 13 | /// 14 | static readonly Lazy @default = new(() => new Base10Alphabet("0123456789")); 15 | 16 | /// 17 | /// Standard Base10 alphabet ("0123456789"). 18 | /// 19 | public static Base10Alphabet Default => @default.Value; 20 | } -------------------------------------------------------------------------------- /src/Base16Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Alphabet representation for Base16 encodings. 12 | /// 13 | public class Base16Alphabet : CodingAlphabet 14 | { 15 | static readonly Lazy upperCaseAlphabet = new(() => new Base16Alphabet("0123456789ABCDEF")); 16 | 17 | static readonly Lazy lowerCaseAlphabet = new(() => new Base16Alphabet("0123456789abcdef")); 18 | 19 | static readonly Lazy modHexAlphabet = new(() => new Base16Alphabet("cbdefghijklnrtuv")); 20 | 21 | /// 22 | /// Initializes a new instance of the class with 23 | /// case insensitive semantics. 24 | /// 25 | /// Encoding alphabet. 26 | public Base16Alphabet(string alphabet) 27 | : this(alphabet, caseSensitive: false) 28 | { 29 | } 30 | 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | /// Encoding alphabet. 35 | /// If the decoding should be performed case sensitive. 36 | public Base16Alphabet(string alphabet, bool caseSensitive) 37 | : base(16, alphabet) 38 | { 39 | if (!caseSensitive) 40 | { 41 | mapCounterparts(); 42 | } 43 | } 44 | 45 | /// 46 | /// Gets upper case Base16 alphabet. 47 | /// 48 | public static Base16Alphabet UpperCase { get; } = upperCaseAlphabet.Value; 49 | 50 | /// 51 | /// Gets lower case Base16 alphabet. 52 | /// 53 | public static Base16Alphabet LowerCase { get; } = lowerCaseAlphabet.Value; 54 | 55 | /// 56 | /// Gets ModHex Base16 alphabet, used by Yubico apps. 57 | /// 58 | public static Base16Alphabet ModHex { get; } = modHexAlphabet.Value; 59 | 60 | /// 61 | /// Gets a value indicating whether the decoding should be performed in a case sensitive fashion. 62 | /// The default is false. 63 | /// 64 | public bool CaseSensitive { get; } 65 | 66 | void mapCounterparts() 67 | { 68 | int alphaLen = Value.Length; 69 | for (int i = 0; i < alphaLen; i++) 70 | { 71 | char c = Value[i]; 72 | if (char.IsLetter(c)) 73 | { 74 | if (char.IsUpper(c)) 75 | { 76 | Map(char.ToLowerInvariant(c), i); 77 | } 78 | 79 | if (char.IsLower(c)) 80 | { 81 | Map(char.ToUpperInvariant(c), i); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Base2.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | using System.IO; 8 | using System.Threading.Tasks; 9 | 10 | namespace SimpleBase; 11 | 12 | /// 13 | /// Base2 implementation that encodes a byte array into 1 and 0's by converting 14 | /// each byte indiviudually by encoding most-significant byte first. 15 | /// 16 | public class Base2 : IBaseCoder, INonAllocatingBaseCoder, IBaseStreamCoder 17 | { 18 | static readonly Lazy @default = new(() => new Base2()); 19 | 20 | /// 21 | /// Default instance of Base2 22 | /// 23 | public static Base2 Default => @default.Value; 24 | 25 | /// 26 | /// Initializes a new instance of the class. 27 | /// 28 | public Base2() 29 | { 30 | } 31 | 32 | /// 33 | public byte[] Decode(ReadOnlySpan text) 34 | { 35 | if (text.Length % 8 != 0) 36 | { 37 | throw new ArgumentException("Input length must be multiply of 8", nameof(text)); 38 | } 39 | 40 | var output = new byte[text.Length / 8]; 41 | if (!internalDecode(text, output, out _)) 42 | { 43 | throw new ArgumentException("Invalid Base2 character encountered", nameof(text)); 44 | } 45 | 46 | return output; 47 | } 48 | 49 | /// 50 | public void Decode(TextReader input, Stream output) 51 | { 52 | StreamHelper.Decode(input, output, input => Decode(input.Span)); 53 | } 54 | 55 | /// 56 | public async Task DecodeAsync(TextReader input, Stream output) 57 | { 58 | await StreamHelper.DecodeAsync(input, output, input => Decode(input.Span)); 59 | } 60 | 61 | /// 62 | public string Encode(ReadOnlySpan bytes) 63 | { 64 | int outputLen = bytes.Length * 8; 65 | var output = outputLen < Bits.SafeStackMaxAllocSize ? stackalloc char[outputLen] : new char[outputLen]; 66 | internalEncode(bytes, output); 67 | return new string(output); 68 | } 69 | 70 | /// 71 | public void Encode(Stream input, TextWriter output) 72 | { 73 | StreamHelper.Encode(input, output, (input, lastBlock) => Encode(input.Span)); 74 | } 75 | 76 | /// 77 | public async Task EncodeAsync(Stream input, TextWriter output) 78 | { 79 | await StreamHelper.EncodeAsync(input, output, (input, lastBlock) => Encode(input.Span)); 80 | } 81 | 82 | /// 83 | public int GetSafeByteCountForDecoding(ReadOnlySpan text) 84 | { 85 | return text.Length / 8; 86 | } 87 | 88 | /// 89 | public int GetSafeCharCountForEncoding(ReadOnlySpan buffer) 90 | { 91 | return buffer.Length * 8; 92 | } 93 | 94 | /// 95 | public bool TryDecode(ReadOnlySpan input, Span output, out int bytesWritten) 96 | { 97 | bytesWritten = 0; 98 | int inputLen = input.Length; 99 | if (inputLen == 0) 100 | { 101 | return true; 102 | } 103 | 104 | (int numBlocks, int remainder) = Math.DivRem(inputLen, 8); 105 | if (remainder != 0 || output.Length < numBlocks) 106 | { 107 | // we don't handle non-canonical encoding yet 108 | return false; 109 | } 110 | 111 | return internalDecode(input, output, out bytesWritten); 112 | } 113 | 114 | static bool internalDecode(ReadOnlySpan input, Span output, out int bytesWritten) 115 | { 116 | bytesWritten = 0; 117 | byte pad = 0; 118 | for (int i = 0; i < input.Length; i++) 119 | { 120 | int c = input[i] - '0'; 121 | if ((c & 1) != c) 122 | { 123 | // invalid character 124 | return false; 125 | } 126 | int shift = 7 - (i % 8); 127 | pad |= (byte)(c << shift); 128 | if (shift == 0) 129 | { 130 | output[bytesWritten++] = pad; 131 | pad = 0; 132 | } 133 | } 134 | return true; 135 | } 136 | 137 | /// 138 | public bool TryEncode(ReadOnlySpan input, Span output, out int numCharsWritten) 139 | { 140 | numCharsWritten = 0; 141 | int targetLen = input.Length * 8; 142 | if (output.Length < targetLen) 143 | { 144 | return false; 145 | } 146 | 147 | internalEncode(input, output); 148 | numCharsWritten = targetLen; 149 | return true; 150 | } 151 | 152 | static void internalEncode(ReadOnlySpan input, Span output) 153 | { 154 | for (int i = 0, o = 0; i < input.Length; i++, o += 8) 155 | { 156 | var b = input[i]; 157 | output[o + 0] = (b & 0b1000_0000) != 0 ? '1' : '0'; 158 | output[o + 1] = (b & 0b0100_0000) != 0 ? '1' : '0'; 159 | output[o + 2] = (b & 0b0010_0000) != 0 ? '1' : '0'; 160 | output[o + 3] = (b & 0b0001_0000) != 0 ? '1' : '0'; 161 | output[o + 4] = (b & 0b0000_1000) != 0 ? '1' : '0'; 162 | output[o + 5] = (b & 0b0000_0100) != 0 ? '1' : '0'; 163 | output[o + 6] = (b & 0b0000_0010) != 0 ? '1' : '0'; 164 | output[o + 7] = (b & 0b0000_0001) != 0 ? '1' : '0'; 165 | } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/Base32Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base32 alphabet flavors. 12 | /// 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// Characters. 17 | public class Base32Alphabet(string alphabet) : CodingAlphabet(32, alphabet, caseInsensitive: true) 18 | { 19 | static readonly Lazy rfc4648Alphabet = new 20 | (() => new Base32Alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")); 21 | 22 | static readonly Lazy extendedHexAlphabet = new 23 | (() => new Base32Alphabet("0123456789ABCDEFGHIJKLMNOPQRSTUV")); 24 | 25 | static readonly Lazy extendedHexLowerAlphabet = new 26 | (() => new Base32Alphabet("0123456789abcdefghijklmnopqrstuv")); 27 | 28 | static readonly Lazy zBase32Alphabet = new 29 | (() => new Base32Alphabet("ybndrfg8ejkmcpqxot1uwisza345h769")); 30 | 31 | static readonly Lazy geohashAlphabet = new 32 | (() => new Base32Alphabet("0123456789bcdefghjkmnpqrstuvwxyz")); 33 | 34 | static readonly Lazy bech32Alphabet = new 35 | (() => new Base32Alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l")); 36 | 37 | // this is the same as RFC4648 but with lowercase letters 38 | static readonly Lazy fileCoinAlphabet = new 39 | (() => new Base32Alphabet("abcdefghijklmnopqrstuvwxyz234567")); 40 | 41 | static readonly Lazy crockfordAlphabet = new 42 | (() => new AliasedBase32Alphabet( 43 | "0123456789ABCDEFGHJKMNPQRSTVWXYZ", 44 | [ 45 | new('O', '0'), 46 | new('I', '1'), 47 | new('L', '1'), 48 | ])); 49 | 50 | static readonly Lazy base32HAlphabet = new( 51 | () => new AliasedBase32Alphabet( 52 | "0123456789ABCDEFGHJKLMNPQRTVWXYZ", 53 | paddingChar: '0', 54 | PaddingPosition.Start, 55 | [ 56 | new('O', '0'), 57 | new('I', '1'), 58 | new('S', '5'), 59 | new('U', 'V'), 60 | ])); 61 | 62 | /// 63 | /// Initializes a new instance of the class. 64 | /// 65 | /// Encoding alphabet to use. 66 | /// Padding character. 67 | /// Position of the padding characters in the encoder output. 68 | public Base32Alphabet(string alphabet, char paddingChar, PaddingPosition paddingPosition) 69 | : this(alphabet) 70 | { 71 | PaddingChar = paddingChar; 72 | PaddingPosition = paddingPosition; 73 | } 74 | 75 | /// 76 | /// Gets Crockford alphabet. 77 | /// gpg 78 | public static Base32Alphabet Crockford => crockfordAlphabet.Value; 79 | 80 | /// 81 | /// Gets RFC4648 alphabet. 82 | /// 83 | public static Base32Alphabet Rfc4648 => rfc4648Alphabet.Value; 84 | 85 | /// 86 | /// Gets Extended Hex alphabet. 87 | /// 88 | public static Base32Alphabet ExtendedHex => extendedHexAlphabet.Value; 89 | 90 | /// 91 | /// Gets Extended Hex alphabet. 92 | /// 93 | public static Base32Alphabet ExtendedHexLower => extendedHexLowerAlphabet.Value; 94 | 95 | /// 96 | /// Gets z-base-32 alphabet. 97 | /// 98 | public static Base32Alphabet ZBase32 => zBase32Alphabet.Value; 99 | 100 | /// 101 | /// Gets Geohash alphabet. 102 | /// 103 | public static Base32Alphabet Geohash => geohashAlphabet.Value; 104 | 105 | /// 106 | /// Gets FileCoin alphabet. 107 | /// 108 | public static Base32Alphabet FileCoin => fileCoinAlphabet.Value; 109 | 110 | /// 111 | /// Gets Base32H alphabet. 112 | /// 113 | public static Base32Alphabet Base32H => base32HAlphabet.Value; 114 | 115 | /// 116 | /// Gets Bech32 alphabet. 117 | /// 118 | public static Base32Alphabet Bech32 => bech32Alphabet.Value; 119 | 120 | /// 121 | /// Gets the padding character used in encoding. 122 | /// 123 | public char PaddingChar { get; } = '='; 124 | 125 | /// 126 | /// Gets the position of the padding characters in the encoder output. 127 | /// 128 | public PaddingPosition PaddingPosition { get; } = PaddingPosition.End; 129 | } 130 | -------------------------------------------------------------------------------- /src/Base36.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base36 Encoding/Decoding implementation. 12 | /// 13 | /// 14 | /// Base36 doesn't implement a Stream-based interface because it's not feasible to use 15 | /// on large buffers. 16 | /// 17 | /// 18 | /// Initializes a new instance of the class using a custom alphabet. 19 | /// 20 | /// Alphabet to use. 21 | public sealed class Base36(Base36Alphabet alphabet) : DividingCoder(alphabet) 22 | { 23 | static readonly Lazy upperCase = new(() => new Base36(Base36Alphabet.Upper)); 24 | static readonly Lazy lowerCase= new(() => new Base36(Base36Alphabet.Lower)); 25 | 26 | /// 27 | /// Gets the uppercase Base36 encoder. 28 | /// 29 | public static Base36 UpperCase => upperCase.Value; 30 | 31 | /// 32 | /// Gets the lowercase Base36 encoder. 33 | /// 34 | public static Base36 LowerCase => lowerCase.Value; 35 | } 36 | -------------------------------------------------------------------------------- /src/Base36Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base36 encoding/decoding alphabet. 12 | /// 13 | /// Alphabet to use. 14 | public class Base36Alphabet(string alphabet) : CodingAlphabet(36, alphabet, caseInsensitive: true) 15 | { 16 | static readonly Lazy upperAlphabet = new(() => new Base36Alphabet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")); 17 | 18 | static readonly Lazy lowerAlphabet = new(() => new Base36Alphabet("0123456789abcdefghijklmnopqrstuvwxyz")); 19 | 20 | /// 21 | /// Base36 alphabet with numbers and uppercase letters. 22 | /// 23 | public static Base36Alphabet Upper => upperAlphabet.Value; 24 | 25 | /// 26 | /// Base36 alphabet with numbers and lowercase letters. 27 | /// 28 | public static Base36Alphabet Lower => lowerAlphabet.Value; 29 | } -------------------------------------------------------------------------------- /src/Base45Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base45 coding alphabet. 12 | /// 13 | /// The characters that build up the Base45 alphabet. 14 | public class Base45Alphabet(string alphabet) : CodingAlphabet(45, alphabet) 15 | { 16 | static readonly Lazy @default = new 17 | (() => new ("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:")); 18 | 19 | /// 20 | /// Default Base45 alphabet per RFC 9285. 21 | /// 22 | public static Base45Alphabet Default => @default.Value; 23 | } 24 | -------------------------------------------------------------------------------- /src/Base58Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base58 alphabet. 12 | /// 13 | /// 14 | /// Initializes a new instance of the class 15 | /// using a custom alphabet. 16 | /// 17 | /// Alphabet to use. 18 | public sealed class Base58Alphabet(string alphabet) : CodingAlphabet(58, alphabet) 19 | { 20 | static readonly Lazy bitcoinAlphabet = new(() 21 | => new Base58Alphabet("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")); 22 | 23 | static readonly Lazy rippleAlphabet = new(() 24 | => new Base58Alphabet("rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz")); 25 | 26 | static readonly Lazy flickrAlphabet = new(() 27 | => new Base58Alphabet("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ")); 28 | 29 | /// 30 | /// Gets Bitcoin alphabet. Monero also uses this alphabet but only works with MoneroBase58 encoding. 31 | /// 32 | public static Base58Alphabet Bitcoin => bitcoinAlphabet.Value; 33 | 34 | /// 35 | /// Gets Base58 alphabet. 36 | /// 37 | public static Base58Alphabet Ripple => rippleAlphabet.Value; 38 | 39 | /// 40 | /// Gets Flickr alphabet. 41 | /// 42 | public static Base58Alphabet Flickr => flickrAlphabet.Value; 43 | } 44 | -------------------------------------------------------------------------------- /src/Base62.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base62 Encoding/Decoding implementation. 12 | /// 13 | /// 14 | /// Base62 doesn't implement a Stream-based interface because it's not feasible to use 15 | /// on large buffers. 16 | /// 17 | /// 18 | /// Initializes a new instance of the class using a custom alphabet. 19 | /// 20 | /// Alphabet to use. 21 | public sealed class Base62(Base62Alphabet alphabet) : DividingCoder(alphabet) 22 | { 23 | static readonly Lazy defaultAlphabet = new(() => new Base62(Base62Alphabet.Default)); 24 | static readonly Lazy lowerFirst= new(() => new Base62(Base62Alphabet.Alternative)); 25 | 26 | /// 27 | /// Gets the default flavor. 28 | /// 29 | public static Base62 Default => defaultAlphabet.Value; 30 | 31 | /// 32 | /// Gets the alphabet with the lowercase letters first. 33 | /// 34 | public static Base62 LowerFirst => lowerFirst.Value; 35 | } 36 | -------------------------------------------------------------------------------- /src/Base62Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base62 alphabet. 12 | /// 13 | /// 14 | /// Initializes a new instance of the class 15 | /// using a custom alphabet. 16 | /// 17 | /// Alphabet to use. 18 | public sealed class Base62Alphabet(string alphabet) : CodingAlphabet(62, alphabet) 19 | { 20 | static readonly Lazy defaultAlphabet = new(() 21 | => new Base62Alphabet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 22 | 23 | static readonly Lazy alternativeAlphabet = new(() 24 | => new Base62Alphabet("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")); 25 | 26 | /// 27 | /// Gets the standard, most common alphabet. 28 | /// 29 | public static Base62Alphabet Default => defaultAlphabet.Value; 30 | 31 | /// 32 | /// Gets Alternative alphabet. 33 | /// 34 | public static Base62Alphabet Alternative => alternativeAlphabet.Value; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/Base64.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Internal Base64 helpers. 12 | /// 13 | static class Base64 14 | { 15 | const char paddingChar = '='; 16 | 17 | internal static byte[] DecodeUrl(ReadOnlySpan text) 18 | { 19 | string base64 = convertBase64UrlToBase64(text); 20 | return Convert.FromBase64String(base64); 21 | } 22 | 23 | static string convertBase64UrlToBase64(ReadOnlySpan text) 24 | { 25 | int len = text.Length; 26 | if (len == 0) 27 | { 28 | return string.Empty; 29 | } 30 | 31 | // .NET's Base64 decoder requires padding to be present 32 | int padLen = 0; 33 | if (text[len - 1] != paddingChar) 34 | { 35 | padLen = 4 - (len % 4); 36 | } 37 | len += padLen; 38 | Span result = len < Bits.SafeStackMaxAllocSize ? stackalloc char[len] : new char[len]; 39 | for (int i = 0; i < text.Length; i++) 40 | { 41 | result[i] = text[i] switch 42 | { 43 | '-' => '+', 44 | '_' => '/', 45 | _ => text[i] 46 | }; 47 | } 48 | if (padLen > 0) 49 | { 50 | result[text.Length..].Fill(paddingChar); 51 | } 52 | return result.ToString(); 53 | } 54 | 55 | internal static bool TryDecodeUrl(ReadOnlySpan text, Span bytes, out int bytesWritten) 56 | { 57 | string base64 = convertBase64UrlToBase64(text); 58 | return Convert.TryFromBase64Chars(base64.AsSpan(), bytes, out bytesWritten); 59 | } 60 | 61 | static string convertBase64ToBase64Url(string text) 62 | { 63 | // i tried writing custom code to perform this replacement faster 64 | // but it turned out slower despite having half the allocation. 65 | // NOTE: padding char is the same between base64 and base64url 66 | return text.Replace('+', '-').Replace('/', '_'); 67 | } 68 | 69 | static string stripBase64Padding(string base64Text) 70 | { 71 | return base64Text.TrimEnd(paddingChar); 72 | } 73 | 74 | internal static string EncodeUrl(ReadOnlySpan bytes) 75 | { 76 | var base64 = stripBase64Padding(Convert.ToBase64String(bytes)); 77 | return convertBase64ToBase64Url(base64); 78 | } 79 | 80 | internal static string EncodeUrlPadded(ReadOnlySpan bytes) 81 | { 82 | var base64 = Convert.ToBase64String(bytes); 83 | return convertBase64ToBase64Url(base64); 84 | } 85 | 86 | internal static string EncodeWithoutPadding(ReadOnlySpan bytes) 87 | { 88 | return stripBase64Padding(Convert.ToBase64String(bytes)); 89 | } 90 | 91 | internal static byte[] DecodeWithoutPadding(ReadOnlySpan rest) 92 | { 93 | return (rest.Length % 4) switch 94 | { 95 | 0 => Convert.FromBase64String(rest.ToString()), 96 | 2 => Convert.FromBase64String(rest.ToString() + "=="), 97 | 3 => Convert.FromBase64String(rest.ToString() + "="), 98 | _ => throw new ArgumentException("Invalid Base64 string length", nameof(rest)) 99 | }; 100 | } 101 | 102 | internal static bool TryDecodeWithoutPadding(ReadOnlySpan rest, Span bytes, out int bytesWritten) 103 | { 104 | return (rest.Length % 4) switch 105 | { 106 | 0 => Convert.TryFromBase64Chars(rest, bytes, out bytesWritten), 107 | 2 => Convert.TryFromBase64Chars(rest.ToString() + "==", bytes, out bytesWritten), 108 | 3 => Convert.TryFromBase64Chars(rest.ToString() + "=", bytes, out bytesWritten), 109 | _ => throw new ArgumentException("Invalid Base64 string length", nameof(rest)) 110 | }; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Base85Alphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Base85 Alphabet. 12 | /// 13 | /// 14 | /// Initializes a new instance of the class 15 | /// using custom settings. 16 | /// 17 | /// Alphabet to use. 18 | /// Character to substitute for all zero. 19 | /// Character to substitute for all space. 20 | public sealed class Base85Alphabet( 21 | string alphabet, 22 | char? allZeroShortcut = null, 23 | char? allSpaceShortcut = null) : CodingAlphabet(85, alphabet) 24 | { 25 | static readonly Lazy z85 = new(() => new Base85Alphabet( 26 | "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#")); 27 | 28 | static readonly Lazy ascii85 = new(() => new Base85Alphabet( 29 | "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstu", 30 | allZeroShortcut: 'z', 31 | allSpaceShortcut: 'y')); 32 | 33 | static readonly Lazy rfc1924 = new(() => new Base85Alphabet( 34 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")); 35 | 36 | /// 37 | /// Gets ZeroMQ Z85 Alphabet. 38 | /// 39 | public static Base85Alphabet Z85 => z85.Value; 40 | 41 | /// 42 | /// Gets Adobe Ascii85 Alphabet (each character is directly produced by raw value + 33), 43 | /// also known as "btoa" encoding. 44 | /// 45 | public static Base85Alphabet Ascii85 => ascii85.Value; 46 | 47 | /// 48 | /// Gets Base85 encoding defined in RFC 1924. 49 | /// 50 | public static Base85Alphabet Rfc1924 => rfc1924.Value; 51 | 52 | /// 53 | /// Gets the character to be used for "all zeros". 54 | /// 55 | public char? AllZeroShortcut { get; } = allZeroShortcut; 56 | 57 | /// 58 | /// Gets the character to be used for "all spaces". 59 | /// 60 | public char? AllSpaceShortcut { get; } = allSpaceShortcut; 61 | 62 | /// 63 | /// Gets a value indicating whether the alphabet uses one of shortcut characters for all spaces 64 | /// or all zeros. 65 | /// 66 | public bool HasShortcut => AllSpaceShortcut.HasValue || AllZeroShortcut.HasValue; 67 | } 68 | -------------------------------------------------------------------------------- /src/Base85Ipv6.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | using System.Net; 8 | using System.Net.Sockets; 9 | using System.Numerics; 10 | 11 | namespace SimpleBase; 12 | 13 | /// 14 | /// Base85 implementation with additional IPv6 coding functions. 15 | /// 16 | /// 17 | /// RFC 1924 sucks, arguably because it's a very early proposal in the history of IPv6: 18 | /// - It contains special chars: It's prone to be confused with other syntactical elements. 19 | /// It can even cause security issues due to poor escaping, let alone UX problems. 20 | /// - Length gains are usually marginal: IPv6 uses zero elimination to reduce the address representation. 21 | /// - Slow. The algorithm is division based, instead of faster bitwise operations. 22 | /// So, that's why I only included a proof of concept implementation instead of working on optimizing it. 23 | /// RFC 1924 should die, and this code should only be used to support some obscure standard or code somewhere. 24 | /// 25 | /// 26 | /// Initializes a new instance of the class. 27 | /// 28 | /// Coding alphabet. 29 | public class Base85IPv6(Base85Alphabet alphabet) : Base85(alphabet) 30 | { 31 | const int ipv6bytes = 16; 32 | const int ipv6chars = 20; 33 | static readonly BigInteger divisor = new(85); 34 | 35 | /// 36 | /// Encode IPv6 address into RFC 1924 Base85 text. 37 | /// 38 | /// IPv6 address. 39 | /// Encoded text. 40 | public string EncodeIPv6(IPAddress ip) 41 | { 42 | if (ip.AddressFamily != AddressFamily.InterNetworkV6) 43 | { 44 | throw new ArgumentException("Invalid IP address type. RFC 1924 is only defined for IPv6 addresses"); 45 | } 46 | 47 | Span buffer = stackalloc byte[ipv6bytes]; 48 | if (!ip.TryWriteBytes(buffer, out int bytesWritten)) 49 | { 50 | throw new InvalidOperationException($"IPAddress.TryWriteBytes() failed, this should never happen: {ip}"); 51 | } 52 | 53 | var num = new BigInteger(buffer[..bytesWritten], isUnsigned: true, isBigEndian: true); 54 | Span str = stackalloc char[Base85IPv6.ipv6chars]; 55 | for (int n = 0, o = ipv6chars - 1; n < ipv6chars; n++, o--) 56 | { 57 | num = BigInteger.DivRem(num, divisor, out var remainder); 58 | str[o] = Alphabet.Value[(int)remainder]; 59 | } 60 | 61 | return str.ToString(); 62 | } 63 | 64 | /// 65 | /// Decode an RFC 1924 encoded text into an IPv6 address. 66 | /// 67 | /// Encoded text. 68 | /// Decoded IPv6 address. 69 | public IPAddress DecodeIPv6(string text) 70 | { 71 | if (text.Length != ipv6chars) 72 | { 73 | throw new ArgumentException("Invalid encoded IPv6 text length"); 74 | } 75 | 76 | BigInteger num = 0; 77 | for (int n = 0; n < ipv6chars; n++) 78 | { 79 | char c = text[n]; 80 | int value = Alphabet.ReverseLookupTable[c] - 1; 81 | if (value < 0) 82 | { 83 | throw new InvalidOperationException($"Invalid character: {c}"); 84 | } 85 | 86 | num = (num * divisor) + value; 87 | } 88 | 89 | Span buffer = stackalloc byte[ipv6bytes]; 90 | return num.TryWriteBytes(buffer, out int bytesWritten, isUnsigned: false, isBigEndian: true) 91 | ? new IPAddress(buffer[..bytesWritten]) 92 | : throw new InvalidOperationException("Destination buffer is too small"); 93 | } 94 | 95 | /// 96 | /// Try decoding an RFC 1924 encoded text into an IPv6 address. 97 | /// 98 | /// Encoded text. 99 | /// Resulting IPv6 address. 100 | /// True if successful, false otherwise. 101 | public bool TryDecodeIPv6(string text, out IPAddress ip) 102 | { 103 | if (text.Length != ipv6chars) 104 | { 105 | ip = IPAddress.IPv6None; 106 | return false; 107 | } 108 | 109 | BigInteger num = 0; 110 | for (int n = 0; n < ipv6chars; n++) 111 | { 112 | char c = text[n]; 113 | int value = Alphabet.ReverseLookupTable[c] - 1; 114 | if (value < 0) 115 | { 116 | ip = IPAddress.IPv6None; 117 | return false; 118 | } 119 | 120 | num = (num * divisor) + value; 121 | } 122 | 123 | Span buffer = stackalloc byte[ipv6bytes]; 124 | if (!num.TryWriteBytes(buffer, out int bytesWritten, isUnsigned: false, isBigEndian: true)) 125 | { 126 | ip = IPAddress.IPv6None; 127 | return false; 128 | } 129 | 130 | ip = new IPAddress(buffer[..bytesWritten]); 131 | return true; 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/Bits.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SimpleBase 4 | { 5 | /// 6 | /// Helper functions for bit operations. 7 | /// 8 | static class Bits 9 | { 10 | /// 11 | /// Safe one-shot maximum amount to be allocated on stack for temporary buffers and alike. 12 | /// 13 | internal const int SafeStackMaxAllocSize = 1024; 14 | 15 | /// 16 | /// Max decimal digits possible in an unsigned long (64-bit) number. 17 | /// 18 | internal const int MaxUInt64Digits = 20; 19 | 20 | /// 21 | /// Converts a byte array to a hexadecimal string. 22 | /// 23 | /// 24 | /// 25 | internal static ulong BigEndianBytesToUInt64(ReadOnlySpan bytes) 26 | { 27 | if (bytes.Length > sizeof(ulong)) 28 | { 29 | throw new ArgumentOutOfRangeException(nameof(bytes), "Span too long to convert to UInt64"); 30 | } 31 | 32 | ulong result = 0; 33 | for (int i = 0; i < bytes.Length; i++) 34 | { 35 | result = (result << 8) | bytes[i]; 36 | } 37 | return result; 38 | } 39 | 40 | /// 41 | /// Converts a UInt64 to a byte array in big-endian order. 42 | /// 43 | /// Value to convert. 44 | /// Output buffer. 45 | /// If the buffer is too small. 46 | internal static void UInt64ToBigEndianBytes(ulong value, Span output) 47 | { 48 | if (output.Length < sizeof(ulong)) 49 | { 50 | throw new ArgumentException("Output is too small", nameof(output)); 51 | } 52 | int byteCount = sizeof(ulong); 53 | for (int i = byteCount - 1; i >= 0; i--) 54 | { 55 | output[i] = (byte)(value & 0xFF); 56 | value >>= 8; 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/CharMap.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | namespace SimpleBase; 7 | 8 | record struct CharMap(char From, char To); 9 | -------------------------------------------------------------------------------- /src/CodingAlphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | using System.Diagnostics; 8 | 9 | namespace SimpleBase; 10 | 11 | /// 12 | /// A single encoding algorithm can support many different alphabets. 13 | /// EncodingAlphabet consists of a basis for implementing different 14 | /// alphabets for different encodings. It's suitable if you want to 15 | /// implement your own encoding based on the existing base classes. 16 | /// 17 | /// 18 | /// This only supports alphabets with lower ASCII character set (0-127). 19 | /// 20 | public abstract class CodingAlphabet : ICodingAlphabet 21 | { 22 | /// 23 | /// Specifies the highest possible char value in an encoding alphabet. 24 | /// Any char above this would raise an exception. 25 | /// 26 | const int maxLength = 127; 27 | 28 | /// 29 | /// Holds a mapping from character to an actual byte value 30 | /// The values are held as "value + 1" so a zero would denote "not set" 31 | /// and would cause an exception. 32 | /// 33 | /// byte[] has no discernible perf impact and saves memory. 34 | readonly byte[] reverseLookupTable = new byte[maxLength]; 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// Length of the alphabe. 40 | /// Alphabet character. 41 | /// Use case-insensitive matching when decoding. 42 | public CodingAlphabet(int length, string alphabet, bool caseInsensitive = false) 43 | { 44 | if (alphabet.Length != length) 45 | { 46 | throw new ArgumentException($"Required alphabet length is {length} but provided alphabet is " 47 | + $"{alphabet.Length} characters long"); 48 | } 49 | 50 | Length = length; 51 | Value = alphabet; 52 | for (short i = 0; i < length; i++) 53 | { 54 | char c = alphabet[i]; 55 | if (caseInsensitive && char.IsLetter(c)) 56 | { 57 | char c2 = char.IsUpper(c) ? char.ToLower(c) : char.ToUpper(c); 58 | if (alphabet.Contains(c2)) 59 | { 60 | throw new ArgumentException($"Case-sensitivity can't be selected with an alphabet that contains both cases of the same letter", nameof(caseInsensitive)); 61 | } 62 | Map(c2, i); 63 | } 64 | Map(c, i); 65 | } 66 | } 67 | 68 | /// 69 | /// Gets the length of the alphabet. 70 | /// 71 | public int Length { get; } 72 | 73 | /// 74 | /// Gets the characters of the alphabet. 75 | /// 76 | public string Value { get; } 77 | 78 | internal ReadOnlySpan ReverseLookupTable => reverseLookupTable; 79 | 80 | /// 81 | /// Generates a standard invalid character exception for alphabets. 82 | /// 83 | /// 84 | /// The reason this is not a throwing method itself is 85 | /// that the compiler has no way of knowing whether the execution 86 | /// will end after the method call and can incorrectly assume 87 | /// reachable code. 88 | /// 89 | /// Characters. 90 | /// Exception to be thrown. 91 | public static Exception InvalidCharacter(char c) 92 | { 93 | return new ArgumentException($"Invalid character: {c}"); 94 | } 95 | 96 | /// 97 | /// Get the string representation of the alphabet. 98 | /// 99 | /// The characters of the encoding alphabet. 100 | public override string ToString() 101 | { 102 | return Value; 103 | } 104 | 105 | /// 106 | public override int GetHashCode() 107 | { 108 | return Value.GetHashCode(StringComparison.Ordinal); 109 | } 110 | 111 | /// 112 | /// Map a character to a value. 113 | /// 114 | /// Characters. 115 | /// Corresponding value. 116 | protected void Map(char c, int value) 117 | { 118 | Debug.Assert(c < maxLength, $"Alphabet contains character above {maxLength}"); 119 | reverseLookupTable[c] = (byte)(value + 1); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/IBaseCoder.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Basic encoding functionality. 12 | /// 13 | public interface IBaseCoder 14 | { 15 | /// 16 | /// Encode a buffer to base-encoded representation. 17 | /// 18 | /// Bytes to encode. 19 | /// Base16 string. 20 | string Encode(ReadOnlySpan bytes); 21 | 22 | /// 23 | /// Decode base-encoded text into bytes. 24 | /// 25 | /// Base16 text. 26 | /// Decoded bytes. 27 | byte[] Decode(ReadOnlySpan text); 28 | } 29 | -------------------------------------------------------------------------------- /src/IBaseStreamCoder.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System.IO; 7 | using System.Threading.Tasks; 8 | 9 | namespace SimpleBase; 10 | 11 | /// 12 | /// Stream-based encoding functionality. 13 | /// 14 | public interface IBaseStreamCoder 15 | { 16 | /// 17 | /// Encodes stream of bytes into base-encoded text. 18 | /// 19 | /// Stream that provides bytes to be encoded. 20 | /// Stream that the encoded text is written to. 21 | void Encode(Stream input, TextWriter output); 22 | 23 | /// 24 | /// Encodes stream of bytes into base-encoded text. 25 | /// 26 | /// Stream that provides bytes to be encoded. 27 | /// Stream that the encoded text is written to. 28 | /// A representing the asynchronous operation. 29 | Task EncodeAsync(Stream input, TextWriter output); 30 | 31 | /// 32 | /// Decode base-encoded text through streams. Stream based variant tries to consume 33 | /// as little memory as possible, and relies of .NET's own underlying buffering mechanisms, 34 | /// contrary to their buffer-based versions. 35 | /// 36 | /// Stream that the encoded bytes would be read from. 37 | /// Stream where decoded bytes will be written to. 38 | void Decode(TextReader input, Stream output); 39 | 40 | /// 41 | /// Decode base-encoded text through streams. Stream based variant tries to consume 42 | /// as little memory as possible, and relies of .NET's own underlying buffering mechanisms, 43 | /// contrary to their buffer-based versions. 44 | /// 45 | /// Stream that the encoded bytes would be read from. 46 | /// Stream where decoded bytes will be written to. 47 | /// A representing the asynchronous operation. 48 | Task DecodeAsync(TextReader input, Stream output); 49 | } 50 | -------------------------------------------------------------------------------- /src/ICodingAlphabet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | namespace SimpleBase; 7 | 8 | /// 9 | /// Defines basic encoding alphabet. 10 | /// 11 | public interface ICodingAlphabet 12 | { 13 | /// 14 | /// Gets the characters in the alphabet. 15 | /// 16 | string Value { get; } 17 | 18 | /// 19 | /// Gets the length of the alphabet. 20 | /// 21 | int Length { get; } 22 | } 23 | -------------------------------------------------------------------------------- /src/INonAllocatingBaseCoder.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Efficient encoding functionality using pre-allocated memory buffers by the callers. 12 | /// 13 | public interface INonAllocatingBaseCoder 14 | { 15 | /// 16 | /// Encode a buffer into a base-encoded representation using pre-allocated buffers. 17 | /// 18 | /// Bytes to encode. 19 | /// Output buffer. 20 | /// Actual number of characters written to the output. 21 | /// Whether encoding was successful or not. If false, 22 | /// will be zero and the content of will be undefined. 23 | bool TryEncode(ReadOnlySpan input, Span output, out int numCharsWritten); 24 | 25 | /// 26 | /// Decode an encoded character buffer into a pre-allocated output buffer. 27 | /// 28 | /// Encoded text. 29 | /// Output buffer. 30 | /// Actual number of bytes written to the output. 31 | /// Whether decoding was successful. If false, the value of 32 | /// will be zero and the content of will be undefined. 33 | bool TryDecode(ReadOnlySpan input, Span output, out int bytesWritten); 34 | 35 | /// 36 | /// Gets a safe estimation about how many bytes decoding will take without performing 37 | /// the actual decoding operation. The estimation can be slightly larger than the actual 38 | /// output size. 39 | /// 40 | /// Text to be decoded. 41 | /// Number of estimated bytes, or zero if the input length is invalid. 42 | int GetSafeByteCountForDecoding(ReadOnlySpan text); 43 | 44 | /// 45 | /// Gets a safe estimation about how many characters encoding a buffer will take without 46 | /// performing the actual encoding operation. The estimation can be slightly larger than the 47 | /// actual output size. 48 | /// 49 | /// Bytes to be encoded. 50 | /// Number of estimated characters, or zero if the input length is invalid. 51 | int GetSafeCharCountForEncoding(ReadOnlySpan buffer); 52 | } 53 | -------------------------------------------------------------------------------- /src/INumericBaseCoder.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | 8 | namespace SimpleBase; 9 | 10 | /// 11 | /// Number-based coding functions. 12 | /// 13 | public interface INumericBaseCoder 14 | { 15 | /// 16 | /// Encode the given number. 17 | /// 18 | /// Number to encode. 19 | /// Encoded string. 20 | /// Negative numbers are not supported. 21 | /// If number is negative. 22 | string Encode(long number); 23 | 24 | /// 25 | /// Encode the given number. 26 | /// 27 | /// Number to encode. 28 | /// Encoded string. 29 | string Encode(ulong number); 30 | 31 | /// 32 | /// Decode text to a number. 33 | /// 34 | /// Text to decode. 35 | /// Decoded number. 36 | /// 37 | /// If the decoded number is larger to fit in a variable or is negative. 38 | /// 39 | long DecodeInt64(string text); 40 | 41 | /// 42 | /// Decode text to a number. 43 | /// 44 | /// Text to decode. 45 | /// Decoded number. 46 | /// 47 | /// If the decoded number is larger to fit in a variable. 48 | /// 49 | ulong DecodeUInt64(string text); 50 | 51 | /// 52 | /// Try to decode text into a number without throwing an exception. 53 | /// 54 | /// Input text. 55 | /// Output number. 56 | /// True if successful, false otherwise. 57 | bool TryDecodeUInt64(string text, out ulong number); 58 | } 59 | -------------------------------------------------------------------------------- /src/MultibaseEncoding.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | namespace SimpleBase; 7 | 8 | /// 9 | /// Currently supported Multibase encodings. 10 | /// 11 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member 12 | public enum MultibaseEncoding 13 | { 14 | // marked as "final" in the spec at https://github.com/multiformats/multibase/blob/master/multibase.csv 15 | Base16Lower = 'f', 16 | Base16Upper = 'F', 17 | Base32Lower = 'b', 18 | Base32Upper = 'B', 19 | Base58Bitcoin = 'z', 20 | Base64 = 'm', 21 | Base64Pad = 'M', 22 | Base64Url = 'u', 23 | Base64UrlPad = 'U', 24 | 25 | // marked as "draft" 26 | Base8 = '7', 27 | Base10 = '9', 28 | Base32Z = 'h', 29 | Base36Lower = 'k', 30 | Base36Upper = 'K', 31 | Base45 = 'R', 32 | 33 | // marked as "experimental" 34 | Base2 = '0', 35 | Base58Flickr = 'Z', 36 | Base32HexLower = 'v', 37 | Base32HexUpper = 'V', 38 | 39 | Base256Emoji = 0xD83D, // high surrogate of '🚀' UTF-16 pair - ends with low surrogate 0xDE80 40 | } 41 | #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member 42 | -------------------------------------------------------------------------------- /src/PaddingPosition.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | namespace SimpleBase; 7 | 8 | /// 9 | /// Position of the padding in an encoder output. 10 | /// 11 | public enum PaddingPosition 12 | { 13 | /// 14 | /// Padding appears at the start of the encoded buffer. 15 | /// 16 | Start, 17 | 18 | /// 19 | /// Padding appears at the end of the buffer. 20 | /// 21 | End, 22 | } 23 | -------------------------------------------------------------------------------- /src/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | using System.Runtime.CompilerServices; 8 | 9 | // force compatibility with non-C# 10 | [assembly: CLSCompliant(true)] 11 | [assembly: InternalsVisibleTo("SimpleBaseTest, PublicKey=0024000004800000140100000602000000240000525341310008000001000100612a9127f475475ffe4a714331c292aeb9e670d2ae238e869142c4517eaa1d4fc4ef75682cd225276aebff330203bd5ef86e3efb2f4fbe13977f94e715a60f5263ff357a8f610ffee280a446ff67c3800cd7d4ca20e7040c107a6b6a83da50427966a822c20c06c57b88e5dde58f3a44623e49ad0bf089a526b83100dc1fc78f6a75ffaa34e764075726e58e1e5fb01ec0c4c9274e99b3136cbbbd25f1fd0302b62bff2fffc3667a4214f58d19d5d06a30b9de959a054823fbb2c0d011f29c928ce9eeb93a88189a3e5ed135f4f3fff3aec36282e6d1acdf8a8c076ab8860498c4b734a19fd214187b4d9823f6b9b52d913307351f9cd9c66d29c258247824c1")] 12 | [assembly: InternalsVisibleTo("Benchmark, PublicKey=0024000004800000140100000602000000240000525341310008000001000100612a9127f475475ffe4a714331c292aeb9e670d2ae238e869142c4517eaa1d4fc4ef75682cd225276aebff330203bd5ef86e3efb2f4fbe13977f94e715a60f5263ff357a8f610ffee280a446ff67c3800cd7d4ca20e7040c107a6b6a83da50427966a822c20c06c57b88e5dde58f3a44623e49ad0bf089a526b83100dc1fc78f6a75ffaa34e764075726e58e1e5fb01ec0c4c9274e99b3136cbbbd25f1fd0302b62bff2fffc3667a4214f58d19d5d06a30b9de959a054823fbb2c0d011f29c928ce9eeb93a88189a3e5ed135f4f3fff3aec36282e6d1acdf8a8c076ab8860498c4b734a19fd214187b4d9823f6b9b52d913307351f9cd9c66d29c258247824c1")] -------------------------------------------------------------------------------- /src/PublicAPI.Unshipped.txt: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /src/SimpleBase.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0 4 | SimpleBase 5 | SimpleBase 6 | Copyright 2014-2025 Sedat Kapanoglu 7 | Sedat Kapanoglu 8 | Base16, Base32, Base45, Base58, Base62, Base85 encoding/decoding library 9 | false 10 | true 11 | true 12 | ..\SimpleBase.snk 13 | false 14 | 15 | 5.4.1 16 | SimpleBase.xml 17 | https://github.com/ssg/SimpleBase 18 | Apache-2.0 19 | false 20 | base16 base32 base36 base45 base58 base62 base85 ascii85 z85 base2 base8 base10 hexadecimal bitcoin ripple flickr crockford extended hex rfc4648 z-base-32 geohash bech32 rfc1924 21 | latest 22 | enable 23 | AnyCPU 24 | README.md 25 | 26 | 30 | 31 | 32 | 33 | True 34 | 9999 35 | 36 | 37 | True 38 | 9999 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | all 63 | runtime; build; native; contentfiles; analyzers; buildtransitive 64 | 65 | 66 | 67 | all 68 | runtime; build; native; contentfiles; analyzers; buildtransitive 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/StreamHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2025 Sedat Kapanoglu 3 | // Licensed under Apache-2.0 License (see LICENSE.txt file for details) 4 | // 5 | 6 | using System; 7 | using System.IO; 8 | using System.Threading.Tasks; 9 | 10 | namespace SimpleBase; 11 | 12 | /// 13 | /// Provides Stream functionality to any buffer-based encoding operation. 14 | /// 15 | static class StreamHelper 16 | { 17 | const int defaultBufferSize = 4096; 18 | 19 | public static void Encode( 20 | Stream input, 21 | TextWriter output, 22 | Func, bool, string> bufferEncodeFunc, 23 | int bufferSize = defaultBufferSize) 24 | { 25 | var buffer = new byte[bufferSize]; 26 | while (true) 27 | { 28 | int bytesRead = input.Read(buffer, 0, bufferSize); 29 | if (bytesRead < 1) 30 | { 31 | break; 32 | } 33 | 34 | var result = bufferEncodeFunc(buffer.AsMemory(0, bytesRead), bytesRead < bufferSize); 35 | output.Write(result); 36 | } 37 | } 38 | 39 | public static async Task EncodeAsync( 40 | Stream input, 41 | TextWriter output, 42 | Func, bool, string> bufferEncodeFunc, 43 | int bufferSize = defaultBufferSize) 44 | { 45 | var buffer = new byte[bufferSize]; 46 | while (true) 47 | { 48 | int bytesRead = await input.ReadAsync(buffer.AsMemory(0, bufferSize)).ConfigureAwait(false); 49 | if (bytesRead < 1) 50 | { 51 | break; 52 | } 53 | 54 | var result = bufferEncodeFunc(buffer.AsMemory(0, bytesRead), bytesRead < bufferSize); 55 | await output.WriteAsync(result).ConfigureAwait(false); 56 | } 57 | } 58 | 59 | public static void Decode( 60 | TextReader input, 61 | Stream output, 62 | Func, Memory> decodeBufferFunc, 63 | int bufferSize = defaultBufferSize) 64 | { 65 | var buffer = new char[bufferSize]; 66 | while (true) 67 | { 68 | int bytesRead = input.Read(buffer, 0, bufferSize); 69 | if (bytesRead < 1) 70 | { 71 | break; 72 | } 73 | 74 | var result = decodeBufferFunc(buffer.AsMemory(0, bytesRead)); 75 | output.Write(result.Span); 76 | } 77 | } 78 | 79 | public static async Task DecodeAsync( 80 | TextReader input, 81 | Stream output, 82 | Func, Memory> decodeBufferFunc, 83 | int bufferSize = defaultBufferSize) 84 | { 85 | var buffer = new char[bufferSize]; 86 | while (true) 87 | { 88 | int bytesRead = await input.ReadAsync(buffer, 0, bufferSize).ConfigureAwait(false); 89 | if (bytesRead < 1) 90 | { 91 | break; 92 | } 93 | 94 | var result = decodeBufferFunc(buffer.AsMemory(0, bytesRead)); 95 | await output.WriteAsync(result).ConfigureAwait(false); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 3 | "settings": { 4 | "documentationRules": { 5 | "companyName": "Sedat Kapanoglu", 6 | "copyrightText": "Copyright (c) 2014-2025 Sedat Kapanoglu\nLicensed under Apache-2.0 License (see LICENSE.txt file for details)", 7 | "documentInternalElements": false 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/Base10Test.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using NUnit.Framework; 17 | using SimpleBase; 18 | 19 | namespace SimpleBaseTest; 20 | 21 | [TestFixture] 22 | class Base10Test 23 | { 24 | static readonly object[][] zeroPrefixedTestData = 25 | [ 26 | [new byte[] { 0x00, 0x01 }, "01"], 27 | [new byte[] { 0x00, 0x00, 0xFF }, "00255"], 28 | [new byte[] { 0x00, 0x01, 0x00 }, "0256"], 29 | ]; 30 | 31 | static readonly object[][] testData = 32 | [ 33 | [new byte[] { }, ""], 34 | [new byte[] { 0x01, 0x00 }, "256"], 35 | [new byte[] { 0x01, 0x00, 0x00 }, "65536"], 36 | ]; 37 | 38 | [Test] 39 | [TestCaseSource(nameof(testData))] 40 | public void Encode_EncodesCorrectly(byte[] decoded, string encoded) 41 | { 42 | string result = Base10.Default.Encode(decoded); 43 | Assert.That(result, Is.EqualTo(encoded)); 44 | } 45 | 46 | [Test] 47 | [TestCaseSource(nameof(zeroPrefixedTestData))] 48 | public void Encode_ZeroPrefixed_EncodesCorrectly(byte[] decoded, string encoded) 49 | { 50 | string result = Base10.Default.Encode(decoded); 51 | Assert.That(result, Is.EqualTo(encoded)); 52 | } 53 | 54 | [Test] 55 | [TestCaseSource(nameof(testData))] 56 | public void Decode_DecodesCorrectly(byte[] decoded, string encoded) 57 | { 58 | var bytes = Base10.Default.Decode(encoded); 59 | Assert.That(bytes, Is.EqualTo(decoded)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/Base16/LegacyTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | 4 | namespace SimpleBaseTest.Base16Test; 5 | 6 | // these are just primitive tests just to make sure they at least do what they are supposed to. 7 | // we want to move this functionality out in the next release anyway. 8 | [TestFixture] 9 | class LegacyTest 10 | { 11 | [Test] 12 | public void Decode_DecodesBothLowerAndUpperCase() 13 | { 14 | var expectedResult = new byte[] { 0xAB, 0xCD, 0xEF, 0xF0 }; 15 | Assert.Multiple(() => 16 | { 17 | Assert.That(Base16.Decode("ABCDEFF0").ToArray(), Is.EqualTo(expectedResult)); 18 | Assert.That(Base16.Decode("abcdeff0").ToArray(), Is.EqualTo(expectedResult)); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/Base256EmojiTest.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using NUnit.Framework; 3 | using SimpleBase; 4 | 5 | namespace SimpleBaseTest; 6 | 7 | [TestFixture] 8 | public class Base256EmojiTest 9 | { 10 | static readonly string[][] testData = 11 | [ 12 | ["\x00yes mani !", "🚀🏃✋🌈😅🌷🤤😻🌟😅👏"], 13 | ]; 14 | 15 | [Test] 16 | [TestCaseSource(nameof(testData))] 17 | public void Encode_EncodesCorrectly(string decoded, string encoded) 18 | { 19 | var bytes = Encoding.UTF8.GetBytes(decoded); 20 | string result = Base256Emoji.Default.Encode(bytes); 21 | Assert.That(result, Is.EqualTo(encoded)); 22 | } 23 | 24 | [Test] 25 | [TestCaseSource(nameof(testData))] 26 | public void Decode_DecodesCorrectly(string decoded, string encoded) 27 | { 28 | var bytes = Base256Emoji.Default.Decode(encoded); 29 | string result = Encoding.UTF8.GetString(bytes); 30 | Assert.That(result, Is.EqualTo(decoded)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /test/Base2Test.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System; 17 | using NUnit.Framework; 18 | using SimpleBase; 19 | 20 | namespace SimpleBaseTest; 21 | 22 | [TestFixture] 23 | class Base2Test 24 | { 25 | static readonly object[][] testData = 26 | [ 27 | [new byte[] { }, ""], 28 | [new byte[] { 0x00, 0x01, 0x02, 0x03 }, "00000000" + "00000001" + "00000010" + "00000011"], 29 | [new byte[] { 0xFF, 0xFE, 0xFD, 0xFC }, "11111111" + "11111110" + "11111101" + "11111100"], 30 | [new byte[] { 0x00, 0x01, 0x02, 0x03, 0xFF, 0xFE, 0xFD }, "00000000" + "00000001" + "00000010" + "00000011" + "11111111" + "11111110" + "11111101"] 31 | ]; 32 | 33 | static readonly string[] nonCanonicalInput = 34 | [ 35 | "1", 36 | "10", 37 | "101", 38 | "1010", 39 | "101010", 40 | "1010101", 41 | ]; 42 | 43 | [Test] 44 | [TestCaseSource(nameof(testData))] 45 | public void Encode_EncodesCorrectly(byte[] decoded, string encoded) 46 | { 47 | string result = Base2.Default.Encode(decoded); 48 | Assert.That(result, Is.EqualTo(encoded)); 49 | } 50 | 51 | [Test] 52 | [TestCaseSource(nameof(testData))] 53 | public void Decode_DecodesCorrectly(byte[] decoded, string encoded) 54 | { 55 | var bytes = Base2.Default.Decode(encoded); 56 | Assert.That(bytes, Is.EqualTo(decoded)); 57 | } 58 | 59 | [Test] 60 | [TestCaseSource(nameof(nonCanonicalInput))] 61 | public void Decode_NonCanonicalInput_Throws(string nonCanonicalText) 62 | { 63 | Assert.Throws(() => Base2.Default.Decode(nonCanonicalText)); 64 | } 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /test/Base32/Base32AlphabetTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | 4 | namespace SimpleBaseTest.Base32Test; 5 | 6 | [TestFixture] 7 | class Base32AlphabetTest 8 | { 9 | [Test] 10 | public void ctorWithPaddingChar_Works() 11 | { 12 | // alphabet characters are unimportant here 13 | var alpha = new Base32Alphabet("0123456789abcdef0123456789abcdef", '!', PaddingPosition.Start); 14 | Assert.Multiple(() => 15 | { 16 | Assert.That(alpha.PaddingChar, Is.EqualTo('!')); 17 | Assert.That(alpha.PaddingPosition, Is.EqualTo(PaddingPosition.Start)); 18 | }); 19 | } 20 | 21 | [Test] 22 | public void GetSafeByteCountForDecoding_Works() 23 | { 24 | Assert.Multiple(() => 25 | { 26 | Assert.That(Base32.Crockford.GetSafeByteCountForDecoding("12345"), Is.EqualTo(3)); 27 | Assert.That(Base32.Crockford.GetSafeByteCountForDecoding(""), Is.EqualTo(0)); 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/Base32/Bech32Test.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | using System; 4 | using System.Text; 5 | 6 | namespace SimpleBaseTest.Base32Test; 7 | 8 | [TestFixture] 9 | class Bech32Test 10 | { 11 | // test data was genereated with cryptii.com with a custom alphabet 12 | static readonly string[][] testData = 13 | [ 14 | ["", ""], 15 | ["f", "vc======"], 16 | ["fo", "vehs===="], 17 | ["foo", "vehk7==="], 18 | ["foob", "vehk7cs="], 19 | ["fooba", "vehk7cnp"], 20 | ["foobar", "vehk7cnpwg======"], 21 | ["foobar1", "vehk7cnpwgcs===="], 22 | ["foobar12", "vehk7cnpwgcny==="], 23 | ["foobar123", "vehk7cnpwgcnyvc="], 24 | ["foobar1234", "vehk7cnpwgcnyve5"], 25 | ["1234567890123456789012345678901234567890", "xyerxdp4xcmnswfsxyerxdp4xcmnswfsxyerxdp4xcmnswfsxyerxdp4xcmnswfs"], 26 | ]; 27 | 28 | [Test] 29 | [TestCaseSource(nameof(testData))] 30 | public void Encode_ReturnsExpectedValues(string input, string expectedOutput) 31 | { 32 | byte[] bytes = Encoding.ASCII.GetBytes(input); 33 | string result = Base32.Bech32.Encode(bytes, padding: true); 34 | Assert.That(result, Is.EqualTo(expectedOutput)); 35 | } 36 | 37 | [Test] 38 | [TestCaseSource(nameof(testData))] 39 | public void Decode_ReturnsExpectedValues(string expectedOutput, string input) 40 | { 41 | var bytes = Base32.Bech32.Decode(input); 42 | string result = Encoding.ASCII.GetString(bytes); 43 | Assert.That(result, Is.EqualTo(expectedOutput)); 44 | bytes = Base32.Bech32.Decode(input.ToLowerInvariant()); 45 | result = Encoding.ASCII.GetString(bytes); 46 | Assert.That(result, Is.EqualTo(expectedOutput)); 47 | } 48 | 49 | [Test] 50 | public void Encode_NullBytes_ReturnsEmptyString() 51 | { 52 | Assert.That(Base32.Bech32.Encode(null, true), Is.EqualTo(String.Empty)); 53 | } 54 | 55 | [Test] 56 | public void Decode_InvalidInput_ThrowsArgumentException() 57 | { 58 | _ = Assert.Throws(() => Base32.Bech32.Decode("[];',m.")); 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /test/Base32/ExtendedHexTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System; 17 | using System.Text; 18 | using SimpleBase; 19 | using NUnit.Framework; 20 | using System.IO; 21 | 22 | namespace SimpleBaseTest.Base32Test; 23 | 24 | [TestFixture] 25 | class ExtendedHexTest 26 | { 27 | static readonly string[][] testData = 28 | [ 29 | ["", ""], 30 | ["f", "CO======"], 31 | ["fo", "CPNG===="], 32 | ["foo", "CPNMU==="], 33 | ["foob", "CPNMUOG="], 34 | ["fooba", "CPNMUOJ1"], 35 | ["foobar", "CPNMUOJ1E8======"], 36 | ["1234567890123456789012345678901234567890", "64P36D1L6ORJGE9G64P36D1L6ORJGE9G64P36D1L6ORJGE9G64P36D1L6ORJGE9G"], 37 | ]; 38 | 39 | [Test] 40 | [TestCaseSource(nameof(testData))] 41 | public void Encode_Stream_ReturnsExpectedValues(string input, string expectedOutput) 42 | { 43 | byte[] bytes = Encoding.ASCII.GetBytes(input); 44 | using var inputStream = new MemoryStream(bytes); 45 | using var writer = new StringWriter(); 46 | Base32.ExtendedHex.Encode(inputStream, writer, padding: true); 47 | Assert.That(writer.ToString(), Is.EqualTo(expectedOutput)); 48 | } 49 | 50 | [Test] 51 | [TestCaseSource(nameof(testData))] 52 | public void Decode_Stream_ReturnsExpectedValues(string expectedOutput, string input) 53 | { 54 | // upper case 55 | using (var inputStream = new StringReader(input)) 56 | using (var outputStream = new MemoryStream()) 57 | { 58 | Base32.ExtendedHex.Decode(inputStream, outputStream); 59 | string result = Encoding.ASCII.GetString(outputStream.ToArray()); 60 | Assert.That(result, Is.EqualTo(expectedOutput)); 61 | } 62 | 63 | // lower case 64 | using (var inputStream = new StringReader(input.ToLowerInvariant())) 65 | using (var outputStream = new MemoryStream()) 66 | { 67 | Base32.ExtendedHex.Decode(inputStream, outputStream); 68 | string result = Encoding.ASCII.GetString(outputStream.ToArray()); 69 | Assert.That(result, Is.EqualTo(expectedOutput)); 70 | } 71 | } 72 | 73 | [Test] 74 | [TestCaseSource(nameof(testData))] 75 | public void Encode_ReturnsExpectedValues(string input, string expectedOutput) 76 | { 77 | byte[] bytes = Encoding.ASCII.GetBytes(input); 78 | string result = Base32.ExtendedHex.Encode(bytes, padding: true); 79 | Assert.That(result, Is.EqualTo(expectedOutput)); 80 | } 81 | 82 | [Test] 83 | [TestCaseSource(nameof(testData))] 84 | public void Decode_ReturnsExpectedValues(string expectedOutput, string input) 85 | { 86 | var bytes = Base32.ExtendedHex.Decode(input); 87 | string result = Encoding.ASCII.GetString(bytes); 88 | Assert.That(result, Is.EqualTo(expectedOutput)); 89 | bytes = Base32.ExtendedHex.Decode(input.ToLowerInvariant()); 90 | result = Encoding.ASCII.GetString(bytes); 91 | Assert.That(result, Is.EqualTo(expectedOutput)); 92 | } 93 | 94 | [Test] 95 | public void Encode_NullBytes_ReturnsEmptyString() 96 | { 97 | Assert.That(Base32.ExtendedHex.Encode(null, false), Is.EqualTo(String.Empty)); 98 | } 99 | 100 | [Test] 101 | [TestCase("!@#!#@!#@#!@")] 102 | [TestCase("||||")] 103 | public void Decode_InvalidInput_ThrowsArgumentException(string input) 104 | { 105 | _ = Assert.Throws(() => Base32.ExtendedHex.Decode(input)); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /test/Base32/FileCoinTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using SimpleBase; 4 | using NUnit.Framework; 5 | 6 | namespace SimpleBaseTest.Base32Test; 7 | 8 | [TestFixture] 9 | class FileCoinTest 10 | { 11 | static readonly string[][] testData = 12 | [ 13 | ["", ""], 14 | ["f", "my======"], 15 | ["fo", "mzxq===="], 16 | ["foo", "mzxw6==="], 17 | ["foob", "mzxw6yq="], 18 | ["fooba", "mzxw6ytb"], 19 | ["foobar", "mzxw6ytboi======"], 20 | ["foobar1", "mzxw6ytboiyq===="], 21 | ["foobar12", "mzxw6ytboiyte==="], 22 | ["foobar123", "mzxw6ytboiytemy="], 23 | ["1234567890123456789012345678901234567890", "gezdgnbvgy3tqojqgezdgnbvgy3tqojqgezdgnbvgy3tqojqgezdgnbvgy3tqojq"] 24 | ]; 25 | 26 | static readonly object[] byteTestData = 27 | [ 28 | new object[] { new byte[] { 245, 202, 80, 149, 94, 201, 222, 50, 17, 198, 138, 104, 32, 183, 131, 33, 139, 208, 203, 211, 197, 191, 92, 194 }, "6xffbfk6zhpdeeogrjucbn4degf5bs6tyw7vzqq", false }, 29 | ]; 30 | 31 | [Test] 32 | [TestCaseSource(nameof(testData))] 33 | public void Encode_ReturnsExpectedValues(string input, string expectedOutput) 34 | { 35 | byte[] bytes = Encoding.ASCII.GetBytes(input); 36 | string result = Base32.FileCoin.Encode(bytes, padding: true); 37 | Assert.That(result, Is.EqualTo(expectedOutput)); 38 | } 39 | 40 | [Test] 41 | [TestCaseSource(nameof(byteTestData))] 42 | public void Encode_Bytes_ReturnsExpectedValues(byte[] bytes, string expectedOutput, bool padding) 43 | { 44 | string result = Base32.FileCoin.Encode(bytes, padding: padding); 45 | Assert.That(result, Is.EqualTo(expectedOutput)); 46 | } 47 | 48 | [Test] 49 | [TestCaseSource(nameof(testData))] 50 | public void Decode_ReturnsExpectedValues(string expectedOutput, string input) 51 | { 52 | var bytes = Base32.FileCoin.Decode(input); 53 | string result = Encoding.ASCII.GetString(bytes); 54 | Assert.That(result, Is.EqualTo(expectedOutput)); 55 | bytes = Base32.FileCoin.Decode(input.ToLowerInvariant()); 56 | result = Encoding.ASCII.GetString(bytes); 57 | Assert.That(result, Is.EqualTo(expectedOutput)); 58 | } 59 | 60 | [Test] 61 | public void Encode_NullBytes_ReturnsEmptyString() 62 | { 63 | Assert.That(Base32.FileCoin.Encode(null, true), Is.EqualTo(String.Empty)); 64 | } 65 | 66 | [Test] 67 | public void Decode_InvalidInput_ThrowsArgumentException() 68 | { 69 | _ = Assert.Throws(() => Base32.FileCoin.Decode("[];',m.")); 70 | } 71 | } -------------------------------------------------------------------------------- /test/Base32/GeohashTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | 4 | namespace SimpleBaseTest.Base32Test; 5 | 6 | [TestFixture] 7 | class GeohashTest 8 | { 9 | [Test] 10 | public void Decode_SmokeTest() 11 | { 12 | const string input = "ezs42"; 13 | var result = Base32.Geohash.Decode(input); 14 | var expected = new byte[] { 0b01101111, 0b11110000, 0b01000001 }; 15 | Assert.That(result, Is.EqualTo(expected)); 16 | } 17 | 18 | [Test] 19 | public void Encode_SmokeTest() 20 | { 21 | const string expected = "ezs42"; 22 | var input = new byte[] { 0b01101111, 0b11110000, 0b01000001 }; 23 | var result = Base32.Geohash.Encode(input); 24 | Assert.That(result, Is.EqualTo(expected)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/Base32/ZBase32Test.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System; 17 | using System.Text; 18 | using NUnit.Framework; 19 | using SimpleBase; 20 | 21 | namespace SimpleBaseTest.Base32Test; 22 | 23 | [TestFixture] 24 | class ZBase32Test 25 | { 26 | static readonly string[][] testData = 27 | [ 28 | ["", ""], 29 | ["dCode z-base-32", "ctbs63dfrb7n4aubqp114c31"], 30 | [ "Never did sun more beautifully steep", 31 | "j31zc3m1rb1g13byqp4shedpp73gkednciozk7djc34sa5d3rb3ze3mfqy" ], 32 | ]; 33 | 34 | [Test] 35 | [TestCaseSource(nameof(testData))] 36 | public void Encode_ReturnsExpectedValues(string input, string expectedOutput) 37 | { 38 | byte[] bytes = Encoding.ASCII.GetBytes(input); 39 | string result = Base32.ZBase32.Encode(bytes, padding: false); 40 | Assert.That(result, Is.EqualTo(expectedOutput)); 41 | } 42 | 43 | [Test] 44 | [TestCaseSource(nameof(testData))] 45 | public void Decode_ReturnsExpectedValues(string expectedOutput, string input) 46 | { 47 | var bytes = Base32.ZBase32.Decode(input); 48 | string result = Encoding.ASCII.GetString(bytes); 49 | Assert.That(result, Is.EqualTo(expectedOutput)); 50 | bytes = Base32.ZBase32.Decode(input.ToLowerInvariant()); 51 | result = Encoding.ASCII.GetString(bytes); 52 | Assert.That(result, Is.EqualTo(expectedOutput)); 53 | } 54 | 55 | [Test] 56 | public void Encode_NullBytes_ReturnsEmptyString() 57 | { 58 | Assert.That(Base32.ZBase32.Encode(null, padding: false), Is.EqualTo(String.Empty)); 59 | } 60 | 61 | [Test] 62 | public void Decode_InvalidInput_ThrowsArgumentException() 63 | { 64 | _ = Assert.Throws(() => Base32.ZBase32.Decode("[];',m.")); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /test/Base36/LowerCaseTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System.Text; 17 | using NUnit.Framework; 18 | using SimpleBase; 19 | 20 | namespace SimpleBaseTest.Base36Test; 21 | 22 | [TestFixture] 23 | class LowerCaseTest 24 | { 25 | static readonly string[][] testData = 26 | [ 27 | ["", ""], 28 | ["a", "2p"], 29 | ["test", "wanek4"], 30 | ["hello world", "fuvrsivvnfrbjwajo"] 31 | ]; 32 | 33 | [Test] 34 | [TestCaseSource(nameof(testData))] 35 | public void Encode_EncodesCorrectly(string decoded, string encoded) 36 | { 37 | var bytes = Encoding.UTF8.GetBytes(decoded); 38 | string result = Base36.LowerCase.Encode(bytes); 39 | Assert.That(result, Is.EqualTo(encoded)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/Base36/UpperCaseTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System.Text; 17 | using NUnit.Framework; 18 | using SimpleBase; 19 | 20 | namespace SimpleBaseTest.Base36Test; 21 | 22 | [TestFixture] 23 | class UpperCaseTest 24 | { 25 | static readonly string[][] testData = 26 | [ 27 | ["", ""], 28 | ["a", "2P"], 29 | ["test", "WANEK4"], 30 | ["hello world", "FUVRSIVVNFRBJWAJO"] 31 | ]; 32 | 33 | [Test] 34 | [TestCaseSource(nameof(testData))] 35 | public void Encode_EncodesCorrectly(string decoded, string encoded) 36 | { 37 | var bytes = Encoding.UTF8.GetBytes(decoded); 38 | string result = Base36.UpperCase.Encode(bytes); 39 | Assert.That(result, Is.EqualTo(encoded)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/Base45/DefaultTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System; 17 | using System.IO; 18 | using System.Text; 19 | using System.Threading.Tasks; 20 | using NUnit.Framework; 21 | using SimpleBase; 22 | 23 | namespace SimpleBaseTest.Base45Test; 24 | 25 | [TestFixture] 26 | class DefaultTest 27 | { 28 | // test cases taken from https://datatracker.ietf.org/doc/rfc9285/ 29 | static readonly string[][] testData = 30 | [ 31 | ["", ""], 32 | ["AB", "BB8"], 33 | ["base-45", "UJCLQE7W581"], 34 | ["ietf!", "QED8WEX0"], 35 | ["SSG", "1OAQ1"], 36 | ["SSG1", "1OA009"], 37 | ["SSG12", "1OA00951"], 38 | ["SSG123", "1OA009QF6"], 39 | ["A", "K1"], 40 | ]; 41 | 42 | static readonly string[] invalidEncodingInputs = 43 | [ 44 | "1", 45 | "1231", 46 | "1231231", 47 | "???", 48 | ]; 49 | 50 | [Test] 51 | [TestCaseSource(nameof(testData))] 52 | public void Encode_ReturnsCorrectValues(string decoded, string encoded) 53 | { 54 | var bytes = Encoding.UTF8.GetBytes(decoded); 55 | string result = Base45.Default.Encode(bytes); 56 | Assert.That(result, Is.EqualTo(encoded)); 57 | } 58 | 59 | [Test] 60 | [TestCaseSource(nameof(testData))] 61 | public void Decode_ReturnsCorrectValues(string decoded, string encoded) 62 | { 63 | var bytes = Base45.Default.Decode(encoded); 64 | var result = Encoding.UTF8.GetString(bytes); 65 | Assert.That(result, Is.EqualTo(decoded)); 66 | } 67 | 68 | [Test] 69 | [TestCaseSource(nameof(invalidEncodingInputs))] 70 | public void Decode_ThrowsOnInvalidEncoding(string invalidInput) 71 | { 72 | Assert.Throws(() => Base45.Default.Decode(invalidInput)); 73 | } 74 | 75 | [Test] 76 | [TestCaseSource(nameof(testData))] 77 | public void Encode_Stream_EncodesCorrectly(string decoded, string encoded) 78 | { 79 | var bytes = Encoding.UTF8.GetBytes(decoded); 80 | using var input = new MemoryStream(bytes); 81 | using var output = new StringWriter(); 82 | Base45.Default.Encode(input, output); 83 | string result = output.ToString(); 84 | Assert.That(result, Is.EqualTo(encoded)); 85 | } 86 | 87 | [Test] 88 | [TestCaseSource(nameof(testData))] 89 | public void Decode_Stream_DecodesCorrectly(string decoded, string encoded) 90 | { 91 | using var input = new StringReader(encoded); 92 | using var output = new MemoryStream(); 93 | Base45.Default.Decode(input, output); 94 | string result = Encoding.UTF8.GetString(output.ToArray()); 95 | Assert.That(result, Is.EqualTo(decoded)); 96 | } 97 | 98 | [Test] 99 | [TestCaseSource(nameof(testData))] 100 | public async Task EncodeAsync_EncodesCorrectly(string decoded, string encoded) 101 | { 102 | var bytes = Encoding.UTF8.GetBytes(decoded); 103 | using var input = new MemoryStream(bytes); 104 | using var output = new StringWriter(); 105 | await Base45.Default.EncodeAsync(input, output); 106 | string result = output.ToString(); 107 | Assert.That(result, Is.EqualTo(encoded)); 108 | } 109 | 110 | [Test] 111 | [TestCaseSource(nameof(testData))] 112 | public async Task DecodeAsync_DecodesCorrectly(string decoded, string encoded) 113 | { 114 | using var input = new StringReader(encoded); 115 | using var output = new MemoryStream(); 116 | await Base45.Default.DecodeAsync(input, output); 117 | string result = Encoding.UTF8.GetString(output.ToArray()); 118 | Assert.That(result, Is.EqualTo(decoded)); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /test/Base58/Base58AlphabetTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using NUnit.Framework; 17 | using SimpleBase; 18 | using System; 19 | 20 | namespace SimpleBaseTest.Base58Test; 21 | 22 | [TestFixture] 23 | [Parallelizable] 24 | class Base58AlphabetTest 25 | { 26 | [Test] 27 | public void Ctor_InvalidLength_Throws() 28 | { 29 | _ = Assert.Throws(() => new Base58Alphabet("123")); 30 | } 31 | 32 | [Test] 33 | public void GetSafeCharCountForEncoding_Works() 34 | { 35 | var input = new byte[] { 0, 0, 0, 0, 1, 2, 3, 4 }; 36 | Assert.That(Base58.Bitcoin.GetSafeCharCountForEncoding(input), Is.EqualTo(10)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/Base58/Base58CheckTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | using System; 4 | using System.Text; 5 | 6 | namespace SimpleBaseTest.Base58Test; 7 | 8 | [TestFixture] 9 | public class Base58CheckTest 10 | { 11 | // the Base58Check test cases taken from btcutil package at https://github.com/btcsuite/btcutil 12 | // ISC License 13 | 14 | //Copyright(c) 2013-2017 The btcsuite developers 15 | //Copyright(c) 2016-2017 The Lightning Network Developers 16 | 17 | //Permission to use, copy, modify, and distribute this software for any 18 | //purpose with or without fee is hereby granted, provided that the above 19 | //copyright notice and this permission notice appear in all copies. 20 | 21 | //THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 22 | //WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 23 | //MERCHANTABILITY AND FITNESS.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 24 | //ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 25 | //WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 26 | //ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 27 | //OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28 | static readonly object[] testData = 29 | [ 30 | new object[] { 20, "", "3MNQE1X"}, 31 | new object[] { 20, " ", "B2Kr6dBE"}, 32 | new object[] { 20, "-", "B3jv1Aft"}, 33 | new object[] { 20, "0", "B482yuaX"}, 34 | new object[] { 20, "1", "B4CmeGAC"}, 35 | new object[] { 20, "-1", "mM7eUf6kB"}, 36 | new object[] { 20, "11", "mP7BMTDVH"}, 37 | new object[] { 20, "abc", "4QiVtDjUdeq"}, 38 | new object[] { 20, "1234598760", "ZmNb8uQn5zvnUohNCEPP"}, 39 | new object[] { 20, "abcdefghijklmnopqrstuvwxyz", "K2RYDcKfupxwXdWhSAxQPCeiULntKm63UXyx5MvEH2"}, 40 | new object[] { 20, "00000000000000000000000000000000000000000000000000000000000000", "bi1EWXwJay2udZVxLJozuTb8Meg4W9c6xnmJaRDjg6pri5MBAxb9XwrpQXbtnqEoRV5U2pixnFfwyXC8tRAVC8XxnjK"}, 41 | ]; 42 | 43 | [Test] 44 | [TestCaseSource(nameof(testData))] 45 | public void EncodeCheck_ValidInput_ReturnsExpectedResult(int version, string payload, string expectedOutput) 46 | { 47 | var bytes = Encoding.ASCII.GetBytes(payload); 48 | string result = Base58.Bitcoin.EncodeCheck(bytes, (byte)version); 49 | Assert.That(result, Is.EqualTo(expectedOutput)); 50 | } 51 | 52 | [Test] 53 | [TestCaseSource(nameof(testData))] 54 | public void TryDecodeCheck_ValidInput_ReturnsExpectedResult(int expectedVersion, string expectedOutput, string input) 55 | { 56 | Span outputBuffer = new byte[256]; 57 | bool result = Base58.Bitcoin.TryDecodeCheck(input, outputBuffer, out byte actualVersion, out int bytesWritten); 58 | Assert.Multiple(() => 59 | { 60 | Assert.That(result, Is.True); 61 | Assert.That(actualVersion, Is.EqualTo(expectedVersion)); 62 | }); 63 | string output = Encoding.ASCII.GetString(outputBuffer[..bytesWritten]); 64 | Assert.That(output, Is.EqualTo(expectedOutput)); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /test/Base58/BitcoinTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | using System; 18 | using NUnit.Framework; 19 | using SimpleBase; 20 | 21 | namespace SimpleBaseTest.Base58Test; 22 | 23 | [TestFixture] 24 | [Parallelizable] 25 | class BitcoinTest 26 | { 27 | static readonly TestCaseData[] bitcoinTestData = 28 | [ 29 | new TestCaseData("0001", "12"), 30 | new TestCaseData("0000010203", "11Ldp"), 31 | new TestCaseData("009C1CA2CBA6422D3988C735BB82B5C880B0441856B9B0910F", "1FESiat4YpNeoYhW3Lp7sW1T6WydcW7vcE"), 32 | new TestCaseData("000860C220EBBAF591D40F51994C4E2D9C9D88168C33E761F6", "1mJKRNca45GU2JQuHZqZjHFNktaqAs7gh"), 33 | new TestCaseData("00313E1F905554E7AE2580CD36F86D0C8088382C9E1951C44D010203", "17f1hgANcLE5bQhAGRgnBaLTTs23rK4VGVKuFQ"), 34 | new TestCaseData("0000000000", "11111"), 35 | new TestCaseData("1111111111", "2vgLdhi"), 36 | new TestCaseData("FFEEDDCCBBAA", "3CSwN61PP"), 37 | new TestCaseData("00", "1"), 38 | new TestCaseData("21", "a"), 39 | new TestCaseData("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F", "1thX6LZfHDZZKUs92febWaf4WJZnsKRiVwJusXxB7L"), 40 | new TestCaseData("0000000000000000000000000000000000000000000000000000", "11111111111111111111111111"), 41 | ]; 42 | 43 | [Test] 44 | public void Encode_NullBuffer_ReturnsEmptyString() 45 | { 46 | Assert.That(Base58.Bitcoin.Encode(null), Is.EqualTo(String.Empty)); 47 | } 48 | 49 | [Test] 50 | [TestCaseSource(nameof(bitcoinTestData))] 51 | public void Encode_Bitcoin_ReturnsExpectedResults(string input, string expectedOutput) 52 | { 53 | var buffer = Base16.UpperCase.Decode(input); 54 | string result = Base58.Bitcoin.Encode(buffer); 55 | Assert.That(result, Is.EqualTo(expectedOutput)); 56 | } 57 | 58 | [Test] 59 | [TestCaseSource(nameof(bitcoinTestData))] 60 | public void TryEncode_Bitcoin_ReturnsExpectedResults(string input, string expectedOutput) 61 | { 62 | var inputBuffer = Base16.UpperCase.Decode(input); 63 | var outputBuffer = new char[Base58.Bitcoin.GetSafeCharCountForEncoding(inputBuffer)]; 64 | Assert.Multiple(() => 65 | { 66 | Assert.That(Base58.Bitcoin.TryEncode(inputBuffer, outputBuffer, out int numWritten), Is.True); 67 | Assert.That(outputBuffer[..numWritten], Is.EqualTo(expectedOutput)); 68 | }); 69 | } 70 | 71 | [Test] 72 | public void Encode_EmptyBuffer_ReturnsEmptyString() 73 | { 74 | Assert.That(Base58.Bitcoin.Encode([]), Is.EqualTo(String.Empty)); 75 | } 76 | 77 | [Test] 78 | public void Decode_EmptyString_ReturnsEmptyBuffer() 79 | { 80 | var result = Base58.Bitcoin.Decode(String.Empty); 81 | Assert.That(result, Is.Empty); 82 | } 83 | 84 | [Test] 85 | public void TryDecode_EmptyString_ReturnsEmptyBuffer() 86 | { 87 | var result = Base58.Bitcoin.TryDecode(String.Empty, new byte[1], out int bytesWritten); 88 | Assert.Multiple(() => 89 | { 90 | Assert.That(result, Is.True); 91 | Assert.That(bytesWritten, Is.EqualTo(0)); 92 | }); 93 | } 94 | 95 | [Test] 96 | public void Decode_InvalidCharacter_Throws() 97 | { 98 | _ = Assert.Throws(() => Base58.Bitcoin.Decode("?")); 99 | } 100 | 101 | [Test] 102 | public void TryDecode_InvalidCharacter_ReturnsFalse() 103 | { 104 | Assert.That(Base58.Bitcoin.TryDecode("?", new byte[10], out _), Is.False); 105 | } 106 | 107 | [Test] 108 | [TestCaseSource(nameof(bitcoinTestData))] 109 | public void Decode_Bitcoin_ReturnsExpectedResults(string expectedOutput, string input) 110 | { 111 | var buffer = Base58.Bitcoin.Decode(input); 112 | string result = BitConverter.ToString(buffer).Replace("-", "", 113 | StringComparison.Ordinal); 114 | Assert.That(result, Is.EqualTo(expectedOutput)); 115 | } 116 | 117 | [Test] 118 | [TestCaseSource(nameof(bitcoinTestData))] 119 | public void TryDecode_Bitcoin_ReturnsExpectedResults(string expectedOutput, string input) 120 | { 121 | var output = new byte[Base58.Bitcoin.GetSafeByteCountForDecoding(input)]; 122 | var success = Base58.Bitcoin.TryDecode(input, output, out int bytesWritten); 123 | Assert.That(success, Is.True); 124 | string result = BitConverter.ToString(output[..bytesWritten]).Replace("-", "", 125 | StringComparison.Ordinal); 126 | Assert.That(result, Is.EqualTo(expectedOutput)); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /test/Base58/Cb58Test.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | using System; 4 | 5 | namespace SimpleBaseTest.Base58Test; 6 | 7 | [TestFixture] 8 | public class Cb58Test 9 | { 10 | // CB58 test cases have been taken from avalanchego package at https://github.com/ava-labs/avalanchego 11 | // BSD 3-Clause License 12 | // see LICENSE.avalanchego.txt file for details 13 | static readonly TestCaseData[] testData = 14 | [ 15 | new TestCaseData(Array.Empty(), "45PJLL"), 16 | new TestCaseData(new byte[]{ 0}, "1c7hwa"), 17 | new TestCaseData(new byte[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}, "1NVSVezva3bAtJesnUj"), 18 | new TestCaseData(new byte[32] { 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 }, 19 | "SkB92YpWm4Q2ijQHH34cqbKkCZWszsiQgHVjtNeFF2HdvDQU"), 20 | ]; 21 | 22 | [Test] 23 | [TestCaseSource(nameof(testData))] 24 | public void EncodeCheck_ValidInput_ReturnsExpectedResult(byte[] bytes, string expectedOutput) 25 | { 26 | string result = Base58.Bitcoin.EncodeCb58(bytes); 27 | Assert.That(result, Is.EqualTo(expectedOutput)); 28 | } 29 | 30 | [Test] 31 | [TestCaseSource(nameof(testData))] 32 | public void TryDecodeCheck_ValidInput_ReturnsExpectedResult(byte[] expectedOutput, string input) 33 | { 34 | byte[] outputBuffer = new byte[256]; 35 | bool result = Base58.Bitcoin.TryDecodeCb58(input, outputBuffer.AsSpan(), out int bytesWritten); 36 | Assert.Multiple(() => 37 | { 38 | Assert.That(result, Is.True); 39 | Assert.That(outputBuffer[..bytesWritten], Is.EqualTo(expectedOutput)); 40 | }); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /test/Base58/FlickrTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | using System; 18 | using NUnit.Framework; 19 | using SimpleBase; 20 | 21 | namespace SimpleBaseTest.Base58Test; 22 | 23 | [TestFixture] 24 | [Parallelizable] 25 | class FlickrTest 26 | { 27 | static readonly TestCaseData[] flickrTestData = 28 | [ 29 | new TestCaseData("0000010203", "11kCP"), 30 | new TestCaseData("009C1CA2CBA6422D3988C735BB82B5C880B0441856B9B0910F", "1ferHzT4xPnDNxGv3kP7Sv1s6vYCBv7VBe"), 31 | new TestCaseData("000860C220EBBAF591D40F51994C4E2D9C9D88168C33E761F6", "1LijqnBz45gt2ipUhyQyJhfnKTzQaS7FG"), 32 | new TestCaseData("00313E1F905554E7AE2580CD36F86D0C8088382C9E1951C44D010203", "17E1GFanBke5ApGagqFMbzkssS23Rj4ugujUfp"), 33 | new TestCaseData("0000000000", "11111"), 34 | new TestCaseData("1111111111", "2VFkCGH"), 35 | new TestCaseData("FFEEDDCCBBAA", "3crWn61oo"), 36 | new TestCaseData("00", "1"), 37 | new TestCaseData("21", "z"), 38 | ]; 39 | 40 | [Test] 41 | public void Encode_NullBuffer_ReturnsEmptyString() 42 | { 43 | Assert.That(Base58.Flickr.Encode(null), Is.EqualTo(String.Empty)); 44 | } 45 | 46 | [Test] 47 | [TestCaseSource(nameof(flickrTestData))] 48 | public void Encode_Flickr_ReturnsExpectedResults(string input, string expectedOutput) 49 | { 50 | var buffer = Base16.UpperCase.Decode(input); 51 | string result = Base58.Flickr.Encode(buffer); 52 | Assert.That(result, Is.EqualTo(expectedOutput)); 53 | } 54 | 55 | [Test] 56 | [TestCaseSource(nameof(flickrTestData))] 57 | public void TryEncode_Flickr_ReturnsExpectedResults(string input, string expectedOutput) 58 | { 59 | var inputBuffer = Base16.UpperCase.Decode(input); 60 | var outputBuffer = new char[Base58.Flickr.GetSafeCharCountForEncoding(inputBuffer)]; 61 | Assert.Multiple(() => 62 | { 63 | Assert.That(Base58.Flickr.TryEncode(inputBuffer, outputBuffer, out int numWritten), Is.True); 64 | Assert.That(outputBuffer[..numWritten], Is.EqualTo(expectedOutput)); 65 | }); 66 | } 67 | 68 | [Test] 69 | public void Encode_EmptyBuffer_ReturnsEmptyString() 70 | { 71 | Assert.That(Base58.Flickr.Encode([]), Is.EqualTo(String.Empty)); 72 | } 73 | 74 | [Test] 75 | public void Decode_EmptyString_ReturnsEmptyBuffer() 76 | { 77 | var result = Base58.Flickr.Decode(String.Empty); 78 | Assert.That(result, Is.Empty); 79 | } 80 | 81 | [Test] 82 | public void Decode_InvalidCharacter_Throws() 83 | { 84 | _ = Assert.Throws(() => Base58.Flickr.Decode("?")); 85 | } 86 | 87 | [Test] 88 | [TestCaseSource(nameof(flickrTestData))] 89 | public void Decode_Flickr_ReturnsExpectedResults(string expectedOutput, string input) 90 | { 91 | var buffer = Base58.Flickr.Decode(input); 92 | string result = BitConverter.ToString(buffer).Replace("-", "", 93 | StringComparison.Ordinal); 94 | Assert.That(result, Is.EqualTo(expectedOutput)); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /test/Base58/RippleTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | using System; 18 | using NUnit.Framework; 19 | using SimpleBase; 20 | 21 | namespace SimpleBaseTest.Base58Test; 22 | 23 | [TestFixture] 24 | [Parallelizable] 25 | class RippleTest 26 | { 27 | static readonly TestCaseData[] rippleTestData = 28 | [ 29 | new TestCaseData("0000010203", "rrLdF"), 30 | new TestCaseData("009C1CA2CBA6422D3988C735BB82B5C880B0441856B9B0910F", "rENS52thYF4eoY6WsLFf1WrTaWydcWfvcN"), 31 | new TestCaseData("000860C220EBBAF591D40F51994C4E2D9C9D88168C33E761F6", "rmJKR4c2hnG7pJQuHZqZjHE4kt2qw1fg6"), 32 | new TestCaseData("00313E1F905554E7AE2580CD36F86D0C8088382C9E1951C44D010203", "rfCr6gw4cLNnbQ6wGRg8B2LTT1psiKhVGVKuEQ"), 33 | new TestCaseData("0000000000", "rrrrr"), 34 | new TestCaseData("1111111111", "pvgLd65"), 35 | new TestCaseData("FFEEDDCCBBAA", "sUSA4arPP"), 36 | new TestCaseData("00", "r"), 37 | new TestCaseData("21", "2"), 38 | ]; 39 | 40 | [Test] 41 | public void Encode_NullBuffer_ReturnsEmptyString() 42 | { 43 | Assert.That(Base58.Ripple.Encode(null), Is.EqualTo(String.Empty)); 44 | } 45 | 46 | [Test] 47 | [TestCaseSource(nameof(rippleTestData))] 48 | public void Encode_Ripple_ReturnsExpectedResults(string input, string expectedOutput) 49 | { 50 | var buffer = Base16.UpperCase.Decode(input); 51 | string result = Base58.Ripple.Encode(buffer); 52 | Assert.That(result, Is.EqualTo(expectedOutput)); 53 | } 54 | 55 | [Test] 56 | [TestCaseSource(nameof(rippleTestData))] 57 | public void TryEncode_Ripple_ReturnsExpectedResults(string input, string expectedOutput) 58 | { 59 | var inputBuffer = Base16.UpperCase.Decode(input); 60 | var outputBuffer = new char[Base58.Ripple.GetSafeCharCountForEncoding(inputBuffer)]; 61 | Assert.Multiple(() => 62 | { 63 | Assert.That(Base58.Ripple.TryEncode(inputBuffer, outputBuffer, out int numWritten), Is.True); 64 | Assert.That(outputBuffer[..numWritten], Is.EqualTo(expectedOutput)); 65 | }); 66 | } 67 | 68 | [Test] 69 | public void Encode_EmptyBuffer_ReturnsEmptyString() 70 | { 71 | Assert.That(Base58.Ripple.Encode([]), Is.EqualTo(String.Empty)); 72 | } 73 | 74 | [Test] 75 | public void Decode_EmptyString_ReturnsEmptyBuffer() 76 | { 77 | var result = Base58.Ripple.Decode(String.Empty); 78 | Assert.That(result, Is.Empty); 79 | } 80 | 81 | [Test] 82 | public void Decode_InvalidCharacter_Throws() 83 | { 84 | _ = Assert.Throws(() => Base58.Ripple.Decode("?")); 85 | } 86 | 87 | [Test] 88 | [TestCaseSource(nameof(rippleTestData))] 89 | public void Decode_Ripple_ReturnsExpectedResults(string expectedOutput, string input) 90 | { 91 | var buffer = Base58.Ripple.Decode(input); 92 | string result = BitConverter.ToString(buffer).Replace("-", "", 93 | StringComparison.Ordinal); 94 | Assert.That(result, Is.EqualTo(expectedOutput)); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /test/Base62/DefaultTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System; 17 | using System.Text; 18 | using NUnit.Framework; 19 | using SimpleBase; 20 | 21 | namespace SimpleBaseTest.Base62Test; 22 | 23 | [TestFixture] 24 | class DefaultTest 25 | { 26 | static readonly string[][] testData = [ 27 | ["", ""], 28 | ["SSG WAS HERE!", "2ETo47rrJdrFdqI4CP"], 29 | ["\x00\x00SSG WAS HERE!", "002ETo47rrJdrFdqI4CP"], 30 | ["\x00\x00\x00", "000"], 31 | ["A quick brown fox jumps over the lazy dog", "MbW36N4wUwiF8w630WywYtgnrGqMKAxpYKQRT90ZlD5pv9LLGP4wHgd"], 32 | ["A", "13"], 33 | ["AA", "4LR"], 34 | ["AAA", "HwWX"], 35 | ["abc", "QmIN"], 36 | ]; 37 | 38 | [Test] 39 | [TestCaseSource(nameof(testData))] 40 | public void Encode_ReturnsCorrectValues(string input, string expected) 41 | { 42 | var bytes = Encoding.UTF8.GetBytes(input); 43 | var encoded = Base62.Default.Encode(bytes); 44 | Assert.That(encoded, Is.EqualTo(expected)); 45 | } 46 | 47 | [Test] 48 | [TestCaseSource(nameof(testData))] 49 | public void Decode_ReturnsCorrectValues(string decoded, string encoded) 50 | { 51 | var result = Base62.Default.Decode(encoded); 52 | Assert.That(result, Is.EqualTo(decoded)); 53 | } 54 | 55 | [Test] 56 | [TestCaseSource(nameof(testData))] 57 | public void TryDecode_ReturnsCorrectValues(string decoded, string encoded) 58 | { 59 | Span output = stackalloc byte[100]; 60 | var result = Base62.Default.TryDecode(encoded, output, out int bytesWritten); 61 | Assert.That(result, Is.True); 62 | Assert.That(Encoding.UTF8.GetString(output[..bytesWritten]), Is.EqualTo(decoded)); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /test/Base62/LowerFirstTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System; 17 | using System.Text; 18 | using NUnit.Framework; 19 | using SimpleBase; 20 | 21 | namespace SimpleBaseTest.Base62Test; 22 | 23 | [TestFixture] 24 | class LowerFirstTest 25 | { 26 | static readonly string[][] testData = [ 27 | ["", ""], 28 | ["SSG WAS HERE!", "2etO47RRjDRfDQi4cp"], 29 | ["\x00\x00SSG WAS HERE!", "002etO47RRjDRfDQi4cp"], 30 | ["\x00\x00\x00", "000"], 31 | ["A quick brown fox jumps over the lazy dog", "mBw36n4WuWIf8W630wYWyTGNRgQmkaXPykqrt90zLd5PV9llgp4WhGD"], 32 | ["A", "13"], 33 | ["AA", "4lr"], 34 | ["AAA", "hWwx"], 35 | ["abc", "qMin"], 36 | ]; 37 | 38 | [Test] 39 | [TestCaseSource(nameof(testData))] 40 | public void Encode_ReturnsCorrectValues(string input, string expected) 41 | { 42 | var bytes = Encoding.UTF8.GetBytes(input); 43 | string encoded = Base62.LowerFirst.Encode(bytes); 44 | Assert.That(encoded, Is.EqualTo(expected)); 45 | } 46 | 47 | [Test] 48 | [TestCaseSource(nameof(testData))] 49 | public void Decode_ReturnsCorrectValues(string decoded, string encoded) 50 | { 51 | var bytes = Base62.LowerFirst.Decode(encoded); 52 | string result = Encoding.UTF8.GetString(bytes); 53 | Assert.That(result, Is.EqualTo(decoded)); 54 | } 55 | 56 | [Test] 57 | [TestCaseSource(nameof(testData))] 58 | public void TryDecode_ReturnsCorrectValues(string decoded, string encoded) 59 | { 60 | Span output = stackalloc byte[100]; 61 | var result = Base62.LowerFirst.TryDecode(encoded, output, out int bytesWritten); 62 | Assert.That(result, Is.True); 63 | Assert.That(Encoding.UTF8.GetString(output[..bytesWritten]), Is.EqualTo(decoded)); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /test/Base85/Base85AlphabetTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | 4 | namespace SimpleBaseTest.Base85Test; 5 | 6 | [TestFixture] 7 | class Base85AlphabetTest 8 | { 9 | [Test] 10 | public void GetSafeCharCountForEncoding_Buffer_Works() 11 | { 12 | var input = new byte[] { 0, 1, 2, 3 }; 13 | Assert.That(Base85.Ascii85.GetSafeCharCountForEncoding(input), Is.EqualTo(8)); 14 | } 15 | 16 | [Test] 17 | [TestCase(0, 0)] 18 | [TestCase(1, 5)] 19 | [TestCase(2, 6)] 20 | [TestCase(3, 7)] 21 | [TestCase(4, 8)] 22 | [TestCase(5, 10)] 23 | [TestCase(8, 13)] 24 | public void GetSafeCharCountForEncoding_Length_Works(int inputLen, int expectedSize) 25 | { 26 | var buffer = new byte[inputLen]; 27 | Assert.That(Base85.Ascii85.GetSafeCharCountForEncoding(buffer), Is.EqualTo(expectedSize)); 28 | } 29 | 30 | [Test] 31 | public void HasShortcut() 32 | { 33 | Assert.Multiple(() => 34 | { 35 | Assert.That(Base85.Ascii85.Alphabet.HasShortcut, Is.True); 36 | Assert.That(Base85.Z85.Alphabet.HasShortcut, Is.False); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/Base85/Rfc1924Test.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | using System.Net; 4 | 5 | namespace SimpleBaseTest.Base85Test; 6 | 7 | [TestFixture] 8 | public class Rfc1924Test 9 | { 10 | [Test] 11 | [TestCase("1080:0:0:0:8:800:200C:417A", "4)+k&C#VzJ4br>0wv%Yp")] 12 | [TestCase("1080::8:800:200c:417a", "4)+k&C#VzJ4br>0wv%Yp")] 13 | public void EncodeIPv6_WorksCorrectly(string ip, string expectedOutput) 14 | { 15 | var addr = IPAddress.Parse(ip); 16 | Assert.That(Base85.Rfc1924.EncodeIPv6(addr), Is.EqualTo(expectedOutput)); 17 | } 18 | 19 | [Test] 20 | [TestCase("4)+k&C#VzJ4br>0wv%Yp", "1080::8:800:200c:417a")] 21 | public void DecodeIPv6_WorksCorrectly(string encodedText, string expectedIp) 22 | { 23 | var ip = Base85.Rfc1924.DecodeIPv6(encodedText); 24 | Assert.That(ip.ToString(), Is.EqualTo(expectedIp)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/Base85/Z85Test.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | using System; 4 | 5 | namespace SimpleBaseTest.Base85Test; 6 | 7 | class Z85Test 8 | { 9 | static readonly TestCaseData[] testVectors = 10 | [ 11 | new TestCaseData(Array.Empty(), ""), 12 | new TestCaseData(new byte[] { 0x86, 0x4F, 0xD2, 0x6F, 0xB5, 0x59, 0xF7, 0x5B }, "HelloWorld"), 13 | new TestCaseData(new byte[] { 0x11 }, "5D"), 14 | new TestCaseData(new byte[] { 0x11, 0x22 }, "5H4"), 15 | new TestCaseData(new byte[] { 0x11, 0x22, 0x33 }, "5H61"), 16 | new TestCaseData(new byte[] { 0x11, 0x22, 0x33, 0x44 }, "5H620"), 17 | new TestCaseData(new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55 }, "5H620rr"), 18 | new TestCaseData(new byte[] { 0x00, 0x00, 0x00, 0x00 }, "00000"), 19 | new TestCaseData(new byte[] { 0x20, 0x20, 0x20, 0x20 }, "arR^H"), 20 | ]; 21 | 22 | [Test] 23 | [TestCaseSource(nameof(testVectors))] 24 | public void Encode_TestVectors_ShouldEncodeCorrectly(byte[] input, string expectedOutput) 25 | { 26 | var result = Base85.Z85.Encode(input); 27 | Assert.That(result, Is.EqualTo(expectedOutput)); 28 | } 29 | 30 | [Test] 31 | public void Encode_NullBuffer_ReturnsEmptyString() 32 | { 33 | Assert.That(Base85.Z85.Encode(null), Is.EqualTo(String.Empty)); 34 | } 35 | 36 | [Test] 37 | [TestCaseSource(nameof(testVectors))] 38 | public void Decode_TestVectors_ShouldDecodeCorrectly(byte[] expectedOutput, string input) 39 | { 40 | var result = Base85.Z85.Decode(input); 41 | Assert.That(result, Is.EqualTo(expectedOutput)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/Base8Test.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System.Text; 17 | using NUnit.Framework; 18 | using SimpleBase; 19 | 20 | namespace SimpleBaseTest; 21 | 22 | [TestFixture] 23 | class Base8Test 24 | { 25 | static readonly object[][] nonCanonicalTestData = 26 | [ 27 | [new byte[] { 0xFF }, "776"], 28 | [new byte[] { 0xFF, 0xFF }, "777774"], 29 | ]; 30 | 31 | static readonly object[][] testData = 32 | [ 33 | [new byte[] { }, ""], 34 | [new byte[] { 0xFF, 0xFF, 0xFF }, "77777777"], 35 | [new byte[] { 0x00, 0x00, 0x00 }, "00000000"], 36 | [new byte[] { 0xFF, 0xFF, 0xFF }, "77777777"], 37 | [Encoding.UTF8.GetBytes("yes mani !"), "362625631006654133464440102"], 38 | ]; 39 | 40 | [Test] 41 | [TestCaseSource(nameof(testData))] 42 | public void Encode_EncodesCorrectly(byte[] decoded, string encoded) 43 | { 44 | string result = Base8.Default.Encode(decoded); 45 | Assert.That(result, Is.EqualTo(encoded)); 46 | } 47 | 48 | [Test] 49 | [TestCaseSource(nameof(nonCanonicalTestData))] 50 | public void Encode_NonCanonicalData_EncodesCorrectly(byte[] decoded, string encoded) 51 | { 52 | string result = Base8.Default.Encode(decoded); 53 | Assert.That(result, Is.EqualTo(encoded)); 54 | } 55 | 56 | [Test] 57 | [TestCaseSource(nameof(testData))] 58 | public void Decode_DecodesCorrectly(byte[] decoded, string encoded) 59 | { 60 | var bytes = Base8.Default.Decode(encoded); 61 | Assert.That(bytes, Is.EqualTo(decoded)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /test/CodingAlphabetTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014-2025 Sedat Kapanoglu 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | using System; 17 | using NUnit.Framework; 18 | using SimpleBase; 19 | 20 | namespace SimpleBaseTest; 21 | 22 | [TestFixture] 23 | class CodingAlphabetTest 24 | { 25 | class DummyAlphabet(string alphabet) : CodingAlphabet(10, alphabet, caseInsensitive: true) 26 | { 27 | } 28 | 29 | [Test] 30 | public void Ctor_WithBothCasesOfLettersAndCaseInsensitive_ShouldThrow() 31 | { 32 | Assert.Throws(() => new DummyAlphabet("01234567Aa")); 33 | } 34 | 35 | [Test] 36 | public void Ctor_LengthAndAlphabetLengthMismatch_ShouldThrow() 37 | { 38 | Assert.Throws(() => new DummyAlphabet("01234567a")); 39 | } 40 | 41 | [Test] 42 | public void Ctor_ProperArguments_ShouldNotThrow() 43 | { 44 | Assert.DoesNotThrow(() => new DummyAlphabet("01234567ab")); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/EncodingAlphabetTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using SimpleBase; 3 | 4 | namespace SimpleBaseTest; 5 | 6 | [TestFixture] 7 | class EncodingAlphabetTest 8 | { 9 | [Test] 10 | public void ToString_ReturnsValue() 11 | { 12 | var alpha = new Base16Alphabet("0123456789abcdef"); 13 | Assert.That(alpha.ToString(), Is.EqualTo("0123456789abcdef")); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Performance", "CA1825:Avoid zero-length array allocations", Justification = "", Scope = "member", Target = "~M:SimpleBaseTest.Base32Test.CrockfordTest.Encode_SampleInterface_Compiles")] 9 | -------------------------------------------------------------------------------- /test/LICENSE.avalanchego.txt: -------------------------------------------------------------------------------- 1 | Copyright(c) 2020, Ava Labs, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /test/LICENSE.monero-rs.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2023 Monero Rust Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /test/SimpleBase.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0 4 | SimpleBaseTest 5 | SimpleBaseTest 6 | false 7 | true 8 | ..\SimpleBase.snk 9 | false 10 | latest 11 | enable 12 | true 13 | 14 | false 15 | true 16 | 17 | 18 | 1701;1702;CA1016 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | --------------------------------------------------------------------------------