├── .gitattributes
├── .gitignore
├── .travis.yml
├── Directory.Build.props
├── LICENSE
├── Multiformats.Base.sln
├── NuGet.config
├── README.md
├── appveyor.yml
├── src
└── Multiformats.Base
│ ├── Base10.cs
│ ├── Base16.Lower.cs
│ ├── Base16.Upper.cs
│ ├── Base16.cs
│ ├── Base2.cs
│ ├── Base32.HexLower.cs
│ ├── Base32.HexPaddedLower.cs
│ ├── Base32.HexPaddedUpper.cs
│ ├── Base32.HexUpper.cs
│ ├── Base32.Lower.cs
│ ├── Base32.PaddedLower.cs
│ ├── Base32.PaddedUpper.cs
│ ├── Base32.Upper.cs
│ ├── Base32.Z.cs
│ ├── Base32.cs
│ ├── Base58.Btc.cs
│ ├── Base58.Flickr.cs
│ ├── Base58.cs
│ ├── Base64.Normal.cs
│ ├── Base64.Padded.cs
│ ├── Base64.Url.cs
│ ├── Base64.UrlPadded.cs
│ ├── Base64.cs
│ ├── Base8.cs
│ ├── Identity.cs
│ ├── LetterCasing.cs
│ ├── Multibase.cs
│ ├── MultibaseEncoding.cs
│ └── Multiformats.Base.csproj
└── test
└── Multiformats.Base.Tests
├── MultibaseTests.cs
├── Multiformats.Base.Tests.csproj
├── test1.csv
├── test2.csv
├── test3.csv
├── test4.csv
├── test5.csv
└── test6.csv
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | [Xx]64/
19 | [Xx]86/
20 | [Bb]uild/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 |
85 | # Visual Studio profiler
86 | *.psess
87 | *.vsp
88 | *.vspx
89 | *.sap
90 |
91 | # TFS 2012 Local Workspace
92 | $tf/
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 | *.DotSettings.user
101 |
102 | # JustCode is a .NET coding add-in
103 | .JustCode
104 |
105 | # TeamCity is a build add-in
106 | _TeamCity*
107 |
108 | # DotCover is a Code Coverage Tool
109 | *.dotCover
110 |
111 | # NCrunch
112 | _NCrunch_*
113 | .*crunch*.local.xml
114 | nCrunchTemp_*
115 |
116 | # MightyMoose
117 | *.mm.*
118 | AutoTest.Net/
119 |
120 | # Web workbench (sass)
121 | .sass-cache/
122 |
123 | # Installshield output folder
124 | [Ee]xpress/
125 |
126 | # DocProject is a documentation generator add-in
127 | DocProject/buildhelp/
128 | DocProject/Help/*.HxT
129 | DocProject/Help/*.HxC
130 | DocProject/Help/*.hhc
131 | DocProject/Help/*.hhk
132 | DocProject/Help/*.hhp
133 | DocProject/Help/Html2
134 | DocProject/Help/html
135 |
136 | # Click-Once directory
137 | publish/
138 |
139 | # Publish Web Output
140 | *.[Pp]ublish.xml
141 | *.azurePubxml
142 |
143 | # TODO: Un-comment the next line if you do not want to checkin
144 | # your web deploy settings because they may include unencrypted
145 | # passwords
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # NuGet Packages
150 | *.nupkg
151 | # The packages folder can be ignored because of Package Restore
152 | **/packages/*
153 | # except build/, which is used as an MSBuild target.
154 | !**/packages/build/
155 | # Uncomment if necessary however generally it will be regenerated when needed
156 | #!**/packages/repositories.config
157 | # NuGet v3's project.json files produces more ignoreable files
158 | *.nuget.props
159 | *.nuget.targets
160 |
161 | # Microsoft Azure Build Output
162 | csx/
163 | *.build.csdef
164 |
165 | # Microsoft Azure Emulator
166 | ecf/
167 | rcf/
168 |
169 | # Windows Store app package directory
170 | AppPackages/
171 | BundleArtifacts/
172 |
173 | # Visual Studio cache files
174 | # files ending in .cache can be ignored
175 | *.[Cc]ache
176 | # but keep track of directories ending in .cache
177 | !*.[Cc]ache/
178 |
179 | # Others
180 | ClientBin/
181 | [Ss]tyle[Cc]op.*
182 | ~$*
183 | *~
184 | *.dbmdl
185 | *.dbproj.schemaview
186 | *.pfx
187 | *.publishsettings
188 | node_modules/
189 | orleans.codegen.cs
190 |
191 | # RIA/Silverlight projects
192 | Generated_Code/
193 |
194 | # Backup & report files from converting an old project file
195 | # to a newer Visual Studio version. Backup files are not needed,
196 | # because we have git ;-)
197 | _UpgradeReport_Files/
198 | Backup*/
199 | UpgradeLog*.XML
200 | UpgradeLog*.htm
201 |
202 | # SQL Server files
203 | *.mdf
204 | *.ldf
205 |
206 | # Business Intelligence projects
207 | *.rdl.data
208 | *.bim.layout
209 | *.bim_*.settings
210 |
211 | # Microsoft Fakes
212 | FakesAssemblies/
213 |
214 | # GhostDoc plugin setting file
215 | *.GhostDoc.xml
216 |
217 | # Node.js Tools for Visual Studio
218 | .ntvs_analysis.dat
219 |
220 | # Visual Studio 6 build log
221 | *.plg
222 |
223 | # Visual Studio 6 workspace options file
224 | *.opt
225 |
226 | # Visual Studio LightSwitch build output
227 | **/*.HTMLClient/GeneratedArtifacts
228 | **/*.DesktopClient/GeneratedArtifacts
229 | **/*.DesktopClient/ModelManifest.xml
230 | **/*.Server/GeneratedArtifacts
231 | **/*.Server/ModelManifest.xml
232 | _Pvt_Extensions
233 |
234 | # LightSwitch generated files
235 | GeneratedArtifacts/
236 | ModelManifest.xml
237 |
238 | # Paket dependency manager
239 | .paket/paket.exe
240 |
241 | # FAKE - F# Make
242 | .fake/
243 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: csharp
2 | sudo: required
3 | dist: xenial
4 | mono: latest
5 | dotnet: 2.2.300
6 | os:
7 | - linux
8 | - osx
9 |
10 | notifications:
11 | email:
12 | on_success: change
13 | on_failure: always
14 |
15 | branches:
16 | only:
17 | - master
18 |
19 | cache:
20 | bundler: true
21 | directories:
22 | - ./packages
23 | - /.dotnetcli
24 | - $HOME/.nuget/packages
25 | - $HOME/Library/Caches/Homebrew
26 |
27 | before_install:
28 | - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; fi
29 |
30 | install:
31 | - git config --global core.autocrlf input
32 | - git submodule update --init --recursive
33 |
34 | script:
35 | - dotnet build -c Release
36 | - dotnet test -c Release -f netcoreapp2.2 --no-build --no-restore --blame
37 | - mono $HOME/.nuget/packages/xunit.runner.console/*/tools/net452/xunit.console.exe ./test/Multiformats.Base.Tests/bin/Release/net461/Multiformats.Base.Tests.dll
38 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 |
7 |
8 | /Library/Frameworks/Mono.framework/Versions/Current/lib/mono
9 | /usr/lib/mono
10 | /usr/local/lib/mono
11 |
12 |
13 | $(BaseFrameworkPathOverrideForMono)/4.5-api
14 | $(BaseFrameworkPathOverrideForMono)/4.5.1-api
15 | $(BaseFrameworkPathOverrideForMono)/4.5.2-api
16 | $(BaseFrameworkPathOverrideForMono)/4.6-api
17 | $(BaseFrameworkPathOverrideForMono)/4.6.1-api
18 | $(BaseFrameworkPathOverrideForMono)/4.6.2-api
19 | $(BaseFrameworkPathOverrideForMono)/4.7-api
20 | $(BaseFrameworkPathOverrideForMono)/4.7.1-api
21 | $(BaseFrameworkPathOverrideForMono)/4.7.2-api
22 | true
23 |
24 |
25 | {RawFileName};{CandidateAssemblyFiles};{HintPathFromItem};{TargetFrameworkDirectory};$(FrameworkPathOverride)/Facades;$(AssemblySearchPaths)
26 | $(BaseFrameworkPathOverrideForMono)/4.5;$(BaseFrameworkPathOverrideForMono)/4.5/Facades;$(AssemblySearchPaths)
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/multiformats/cs-multibase/c4d63d8cb16fd7d8653d809cd6c5884e85c5622e/LICENSE
--------------------------------------------------------------------------------
/Multiformats.Base.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 15
3 | VisualStudioVersion = 15.0.27130.2010
4 | MinimumVisualStudioVersion = 15.0.26124.0
5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1868BBD8-5963-44BD-B92B-539CF2A79DD2}"
6 | EndProject
7 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Multiformats.Base", "src\Multiformats.Base\Multiformats.Base.csproj", "{CB485F6D-C74E-4419-859D-A1623BB62309}"
8 | EndProject
9 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{593C0817-7D83-4230-B921-FC1E7F0AFD51}"
10 | EndProject
11 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Multiformats.Base.Tests", "test\Multiformats.Base.Tests\Multiformats.Base.Tests.csproj", "{A325E7C4-3F58-4F58-B3DA-395C2928111C}"
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Debug|Any CPU = Debug|Any CPU
16 | Debug|x64 = Debug|x64
17 | Debug|x86 = Debug|x86
18 | Release|Any CPU = Release|Any CPU
19 | Release|x64 = Release|x64
20 | Release|x86 = Release|x86
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Debug|x64.ActiveCfg = Debug|Any CPU
26 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Debug|x64.Build.0 = Debug|Any CPU
27 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Debug|x86.ActiveCfg = Debug|Any CPU
28 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Debug|x86.Build.0 = Debug|Any CPU
29 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Release|x64.ActiveCfg = Release|Any CPU
32 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Release|x64.Build.0 = Release|Any CPU
33 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Release|x86.ActiveCfg = Release|Any CPU
34 | {CB485F6D-C74E-4419-859D-A1623BB62309}.Release|x86.Build.0 = Release|Any CPU
35 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Debug|Any CPU.Build.0 = Debug|Any CPU
37 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Debug|x64.ActiveCfg = Debug|Any CPU
38 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Debug|x64.Build.0 = Debug|Any CPU
39 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Debug|x86.ActiveCfg = Debug|Any CPU
40 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Debug|x86.Build.0 = Debug|Any CPU
41 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Release|Any CPU.Build.0 = Release|Any CPU
43 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Release|x64.ActiveCfg = Release|Any CPU
44 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Release|x64.Build.0 = Release|Any CPU
45 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Release|x86.ActiveCfg = Release|Any CPU
46 | {A325E7C4-3F58-4F58-B3DA-395C2928111C}.Release|x86.Build.0 = Release|Any CPU
47 | EndGlobalSection
48 | GlobalSection(SolutionProperties) = preSolution
49 | HideSolutionNode = FALSE
50 | EndGlobalSection
51 | GlobalSection(NestedProjects) = preSolution
52 | {CB485F6D-C74E-4419-859D-A1623BB62309} = {1868BBD8-5963-44BD-B92B-539CF2A79DD2}
53 | {A325E7C4-3F58-4F58-B3DA-395C2928111C} = {593C0817-7D83-4230-B921-FC1E7F0AFD51}
54 | EndGlobalSection
55 | GlobalSection(ExtensibilityGlobals) = postSolution
56 | SolutionGuid = {9BA78243-1F7F-41B0-9205-F57DF9577A1D}
57 | EndGlobalSection
58 | EndGlobal
59 |
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **This project is no longer maintained and has been archived.**
2 |
3 | # Multiformats.Base
4 |
5 | [](https://github.com/multiformats/multiformats)
6 | [](https://webchat.freenode.net/?channels=%23ipfs)
7 | [](https://travis-ci.org/multiformats/cs-multibase)
8 | [](https://ci.appveyor.com/project/tabrath/cs-multibase)
9 | [](https://www.nuget.org/packages/Multiformats.Base/)
10 | [](https://github.com/RichardLitt/standard-readme)
11 | [](https://codecov.io/gh/multiformats/cs-multibase)
12 | [](https://libraries.io/github/multiformats/cs-multibase)
13 |
14 | > C# implementation of [multiformats/multibase](https://github.com/multiformats/multibase).
15 |
16 | As stated in the specs, multibase encoded strings are prefixed with an identifier for the base it's encoded in.
17 |
18 | ## Table of Contents
19 |
20 | - [Install](#install)
21 | - [Usage](#usage)
22 | - [Supported base encodings](#supported-base-encodings)
23 | - [Maintainers](#maintainers)
24 | - [Contribute](#contribute)
25 | - [License](#license)
26 |
27 | ## Install
28 |
29 | PM> Install-Package Multiformats.Base
30 |
31 | CLI> dotnet install Multiformats.Base
32 |
33 | ## Usage
34 | ``` csharp
35 | using Multiformats.Base;
36 | using System.Text;
37 |
38 | string encoded = Multibase.Encode(MultibaseEncoding.Base32Lower, Encoding.UTF8.GetBytes("hello world"));
39 | // bnbswy3dpeb3w64tmmq
40 | byte[] decoded = Multibase.Decode(encoded, out MultibaseEncoding encoding);
41 | ```
42 |
43 | ## Supported base encodings
44 |
45 | * Identity
46 | * Base2
47 | * Base8
48 | * Base10
49 | * Base16
50 | * Base32
51 | * Lower / Upper
52 | * Padded Lower / Upper
53 | * Hex Lower / Upper
54 | * Hex Padded Lower / Upper
55 | * Z-Base32
56 | * Base58
57 | * Bitcoin
58 | * Flickr
59 | * Base64
60 | * Unpadded / Padded
61 | * UrlSafe Unpadded / Padded
62 |
63 | ## Maintainers
64 |
65 | Captain: [@tabrath](https://github.com/tabrath).
66 |
67 | ## Contribute
68 |
69 | Contributions welcome. Please check out [the issues](https://github.com/multiformats/cs-multibase/issues).
70 |
71 | Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
72 |
73 | Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
74 |
75 | ## License
76 |
77 | [MIT](LICENSE) © 2018 Trond Bråthen
78 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | environment:
2 | PKG_VERSION: 2.0.2
3 | VERSION_SUFFIX: ""
4 | version: ${PKG_VERSION}-{build}
5 | configuration: Release
6 | platform: x64
7 |
8 | skip_commits:
9 | message: /travis/
10 | files:
11 | - '**\*.md'
12 | - LICENSE
13 |
14 | skip_branch_with_pr: true
15 |
16 | matrix:
17 | fast_finish: true
18 |
19 | init:
20 | - git config --global core.autocrlf input
21 | - ps: $env:BUILD_VERSION = "$env:PKG_VERSION-$env:APPVEYOR_BUILD_NUMBER"
22 | - ps: |
23 | if ($env:APPVEYOR_REPO_BRANCH -eq "master")
24 | {
25 | $env:VERSION_SUFFIX = ""
26 | $env:NUGET_VERSION = "$env:PKG_VERSION"
27 | }
28 | else
29 | {
30 | $env:VERSION_SUFFIX = "beta$env:APPVEYOR_BUILD_NUMBER"
31 | $env:NUGET_VERSION = "$env:PKG_VERSION-$env:VERSION_SUFFIX"
32 | }
33 | - ps: Update-AppveyorBuild -Version $env:BUILD_VERSION
34 | - ps: Write-Host "Build version $env:BUILD_VERSION, NuGet version $env:NUGET_VERSION, Version suffix $env:VERSION_SUFFIX"
35 |
36 | install:
37 | - git submodule update --init --recursive
38 |
39 | build_script:
40 | - ps: |
41 | if ($env:APPVEYOR_REPO_BRANCH -eq "master")
42 | {
43 | dotnet build -c $env:CONFIGURATION
44 | }
45 | else
46 | {
47 | dotnet build -c $env:CONFIGURATION --version-suffix $env:VERSION_SUFFIX
48 | }
49 |
50 | test: off
51 |
52 | test_script:
53 | - dotnet test -c %CONFIGURATION% -f netcoreapp2.2 /p:CollectCoverage=true %APPVEYOR_BUILD_FOLDER%\test\Multiformats.Base.Tests
54 |
55 | on_success:
56 | - choco install codecov
57 | - codecov -f "%APPVEYOR_BUILD_FOLDER%\test\Multiformats.Base.Tests\coverage.opencover.xml"
58 |
59 | artifacts:
60 | - path: '**\*.nupkg'
61 | name: nupkg
62 | - path: '**\*.snupkg'
63 | name: snupkg
64 |
65 | cache:
66 | - '%USERPROFILE%\.local'
67 | - '%USERPROFILE%\.nuget\packages -> **\*.csproj'
68 | - '%LocalAppData%\NuGet\Cache'
69 | - '%LocalAppData%\Python'
70 | - '.\packages -> **\project.json'
71 | - '.\tools'
72 | - '\Python34'
73 |
74 | nuget:
75 | account_feed: true
76 |
77 | deploy:
78 | - provider: NuGet
79 | api_key:
80 | secure: WcDqU36pLPvA+s5D4N0VEsi7AZGewvf4croE/D3rh3F+iqiztq9w5gHbrhgoTNS9
81 | on:
82 | branch: master
83 | appveyor_repo_tag: true
84 | - provider: GitHub
85 | description: 'Release description'
86 | auth_token:
87 | secure: nsZHZ5nFBFP4fZoVUEeWeZKx7LUASVqCZ+JblTox+02RfTAOlANdFWeCqOwhu7pk
88 | artifact: /.*\.nupkg/ # upload all NuGet packages to release assets
89 | draft: false
90 | prerelease: false
91 | on:
92 | branch: master # release from master branch only
93 | appveyor_repo_tag: true
94 |
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base10.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Globalization;
3 | using System.Linq;
4 | using System.Numerics;
5 |
6 | namespace Multiformats.Base
7 | {
8 | internal class Base10 : Multibase
9 | {
10 | private static readonly char[] _alphabet = "0123456789".ToCharArray();
11 |
12 | protected override string Name => "base10";
13 | protected override char Prefix => '9';
14 | protected override char[] Alphabet => _alphabet;
15 |
16 | public override byte[] Decode(string input)
17 | {
18 | var big = BigInteger.Parse("00" + input, NumberStyles.None);
19 | return LeadingZeros(input).Concat(big.ToByteArray().Reverse().SkipWhile(b => b == 0)).ToArray();
20 | }
21 |
22 | private static IEnumerable LeadingZeros(IEnumerable input)
23 | {
24 | return Enumerable.Range(0, input.TakeWhile(b => b == '0').Count()).Select(_ => (byte)0x00);
25 | }
26 |
27 | private static IEnumerable LeadingNulls(IEnumerable input)
28 | {
29 | return Enumerable.Range(0, input.TakeWhile(b => b == 0x00).Count()).Select(_ => '0');
30 | }
31 |
32 | public override string Encode(byte[] bytes)
33 | {
34 | var big = new BigInteger(bytes.Reverse().Concat(new byte[]{0x00}).ToArray());
35 | return new string(LeadingNulls(bytes).ToArray()) + big.ToString();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base16.Lower.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base16Lower : Base16
4 | {
5 | private static readonly char[] _alphabet = "0123456789abcdef".ToCharArray();
6 |
7 | protected override string Name => "base16";
8 | protected override char Prefix => 'f';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, LetterCasing.Lower);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, LetterCasing.Lower);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base16.Upper.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base16Upper : Base16
4 | {
5 | private static readonly char[] _alphabet = "0123456789ABCDEF".ToCharArray();
6 |
7 | protected override string Name => "BASE16";
8 | protected override char Prefix => 'F';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, LetterCasing.Upper);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, LetterCasing.Upper);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base16.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 |
5 | namespace Multiformats.Base
6 | {
7 | internal abstract class Base16 : Multibase
8 | {
9 | protected byte[] Decode(string input, LetterCasing casing)
10 | {
11 | if (casing == LetterCasing.Lower && input.Any(char.IsUpper))
12 | input = input.ToLower();
13 |
14 | if (casing == LetterCasing.Upper && input.Any(char.IsLower))
15 | input = input.ToUpper();
16 |
17 | return Enumerable.Range(0, input.Length / 2)
18 | .Select(i => (byte)Convert.ToInt32(input.Substring(i * 2, 2), 16))
19 | .ToArray();
20 | }
21 |
22 | protected string Encode(byte[] input, LetterCasing casing)
23 | {
24 | var format = casing == LetterCasing.Lower ? "{0:x2}" : "{0:X2}";
25 |
26 | return input.Aggregate(new StringBuilder(), (sb, b) => sb.AppendFormat(format, b)).ToString();
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base2.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 |
3 | namespace Multiformats.Base
4 | {
5 | internal class Base2 : Multibase
6 | {
7 | private static readonly char[] _alphabet = { '0', '1' };
8 |
9 | protected override string Name => "base2";
10 | protected override char Prefix => '0';
11 | protected override char[] Alphabet => _alphabet;
12 |
13 | public override byte[] Decode(string input)
14 | {
15 | var bytes = new byte[input.Length / 8];
16 | for (var index = 0; index < input.Length / 8; index++)
17 | {
18 | for (var i = 0; i < 8; i++)
19 | if (input[(index * 8) + i] == '1')
20 | bytes[index] |= (byte)(1 << (7 - i));
21 | }
22 |
23 | return bytes;
24 | }
25 |
26 | public override string Encode(byte[] bytes) => new string(bytes.Select(b => Enumerable.Range(0, 8).Select(i => (b & (1 << i)) != 0 ? '1' : '0').Reverse()).SelectMany(b => b).ToArray());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.HexLower.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32HexLower : Base32
4 | {
5 | private static readonly char[] _alphabet = "0123456789abcdefghijklmnopqrstuv".ToCharArray();
6 |
7 | protected override string Name => "base32hex";
8 | protected override char Prefix => 'v';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, false, LetterCasing.Lower);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, false);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.HexPaddedLower.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32HexPaddedLower : Base32
4 | {
5 | private static readonly char[] _alphabet = "0123456789abcdefghijklmnopqrstuv=".ToCharArray();
6 |
7 | protected override string Name => "base32hexpad";
8 | protected override char Prefix => 't';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, true, LetterCasing.Lower);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, true);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.HexPaddedUpper.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32HexPaddedUpper : Base32
4 | {
5 | private static readonly char[] _alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUV=".ToCharArray();
6 |
7 | protected override string Name => "BASE32HEXPAD";
8 | protected override char Prefix => 'T';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, true, LetterCasing.Upper);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, true);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.HexUpper.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32HexUpper : Base32
4 | {
5 | private static readonly char[] _alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUV".ToCharArray();
6 |
7 | protected override string Name => "BASE32HEX";
8 | protected override char Prefix => 'V';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, false, LetterCasing.Upper);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, false);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.Lower.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32Lower : Base32
4 | {
5 | private static readonly char[] _alphabet = "abcdefghijklmnopqrstuvwxyz234567".ToCharArray();
6 |
7 | protected override string Name => "base32";
8 | protected override char Prefix => 'b';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, false, LetterCasing.Lower);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, false);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.PaddedLower.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32PaddedLower : Base32
4 | {
5 | private static readonly char[] _alphabet = "abcdefghijklmnopqrstuvwxyz234567=".ToCharArray();
6 |
7 | protected override string Name => "base32pad";
8 | protected override char Prefix => 'c';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, true, LetterCasing.Lower);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, true);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.PaddedUpper.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32PaddedUpper : Base32
4 | {
5 | private static readonly char[] _alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=".ToCharArray();
6 |
7 | protected override string Name => "BASE32PAD";
8 | protected override char Prefix => 'C';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, true, LetterCasing.Upper);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, true);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.Upper.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32Upper : Base32
4 | {
5 | private static readonly char[] _alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".ToCharArray();
6 |
7 | protected override string Name => "BASE32";
8 | protected override char Prefix => 'B';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, false, LetterCasing.Upper);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, false);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.Z.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base32Z : Base32
4 | {
5 | private static readonly char[] _alphabet = "ybndrfg8ejkmcpqxot1uwisza345h769".ToCharArray();
6 |
7 | protected override string Name => "base32z";
8 | protected override char Prefix => 'h';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, false, LetterCasing.Ignore);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, false);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base32.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace Multiformats.Base
5 | {
6 | internal abstract class Base32 : Multibase
7 | {
8 | protected byte[] Decode(string input, bool padding, LetterCasing casing)
9 | {
10 | if (padding)
11 | input = input.TrimEnd('=');
12 |
13 | if (casing == LetterCasing.Lower && input.Any(char.IsUpper))
14 | input = input.ToLower();
15 |
16 | if (casing == LetterCasing.Upper && input.Any(char.IsLower))
17 | input = input.ToUpper();
18 |
19 | var bits = 0;
20 | var value = 0;
21 | var index = 0;
22 | var output = new byte[(input.Length * 5 / 8) | 0];
23 |
24 | for (var i = 0; i < input.Length; i++)
25 | {
26 | value = (value << 5) | Array.IndexOf(Alphabet, input[i]);
27 | bits += 5;
28 |
29 | if (bits >= 8)
30 | {
31 | output[index++] = (byte)(((uint)value >> (bits - 8)) & 255);
32 | bits -= 8;
33 | }
34 | }
35 |
36 | return output;
37 | }
38 |
39 | protected string Encode(byte[] bytes, bool padding)
40 | {
41 | int bits = 0;
42 | int value = 0;
43 | string output = "";
44 |
45 | for (var i = 0; i < bytes.Length; i++)
46 | {
47 | value = (value << 8) | bytes[i];
48 | bits += 8;
49 |
50 | while (bits >= 5)
51 | {
52 | output += Alphabet[(int)((uint)value >> (bits - 5)) & 31];
53 | bits -= 5;
54 | }
55 | }
56 |
57 | if (bits > 0)
58 | output += Alphabet[(value << (5 - bits)) & 31];
59 |
60 | if (padding)
61 | {
62 | while ((output.Length % 8) != 0)
63 | output += '=';
64 | }
65 |
66 | return output;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base58.Btc.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base58Btc : Base58
4 | {
5 | private static readonly char[] _alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".ToCharArray();
6 |
7 | protected override string Name => "base58btc";
8 | protected override char Prefix => 'z';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, _alphabet);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, _alphabet);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base58.Flickr.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base58Flickr : Base58
4 | {
5 | private static readonly char[] _alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ".ToCharArray();
6 |
7 | protected override string Name => "base58flickr";
8 | protected override char Prefix => 'Z';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, _alphabet);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, _alphabet);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base58.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Numerics;
5 |
6 | namespace Multiformats.Base
7 | {
8 | internal abstract class Base58 : Multibase
9 | {
10 | protected string Encode(byte[] b, char[] alphabet)
11 | {
12 | return new string(
13 | b.TakeWhile(c => c == 0)
14 | .Select(_ => alphabet[0])
15 | .Concat(ParseBigInt(b.Aggregate(0, (current, t) => current * 256 + t), alphabet).Reverse())
16 | .ToArray());
17 | }
18 |
19 | private static IEnumerable ParseBigInt(BigInteger intData, char[] alphabet)
20 | {
21 | var len = alphabet.Length;
22 | while (intData > 0)
23 | {
24 | var rem = (int)(intData % len);
25 | intData /= len;
26 | yield return alphabet[rem];
27 | }
28 | }
29 |
30 | private static readonly ConcurrentDictionary DecodeMap = new ConcurrentDictionary();
31 |
32 | private static byte[] CreateDecodeMap(char[] alphabet)
33 | {
34 | var map = Enumerable.Range(0, 256).Select(b => (byte)0xFF).ToArray();
35 | for (var i = 0; i < alphabet.Length; i++)
36 | map[alphabet[i]] = (byte)i;
37 | return map;
38 | }
39 |
40 | protected byte[] Decode(string b, char[] alphabet)
41 | {
42 | lock (DecodeMap)
43 | {
44 | var decodeMap = DecodeMap.GetOrAdd(alphabet, CreateDecodeMap);
45 | var len = alphabet.Length;
46 |
47 | return b.TakeWhile(c => c == alphabet[0])
48 | .Select(_ => (byte)0)
49 | .Concat(b.Select(c => decodeMap[c])
50 | .Aggregate(0, (current, c) => current * len + c)
51 | .ToByteArray()
52 | .Reverse()
53 | .SkipWhile(c => c == 0))
54 | .ToArray();
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base64.Normal.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base64Normal : Base64
4 | {
5 | private static readonly char[] _alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".ToCharArray();
6 |
7 | protected override string Name => "base64";
8 | protected override char Prefix => 'm';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, false, false);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, false, false);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base64.Padded.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base64Padded : Base64
4 | {
5 | private static readonly char[] _alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".ToCharArray();
6 |
7 | protected override string Name => "base64pad";
8 | protected override char Prefix => 'M';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, false, true);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, false, true);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base64.Url.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base64Url : Base64
4 | {
5 | private static readonly char[] _alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".ToCharArray();
6 |
7 | protected override string Name => "base64url";
8 | protected override char Prefix => 'u';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, true, false);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, true, false);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base64.UrlPadded.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal class Base64UrlPadded : Base64
4 | {
5 | private static readonly char[] _alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=".ToCharArray();
6 |
7 | protected override string Name => "base64urlpad";
8 | protected override char Prefix => 'U';
9 | protected override char[] Alphabet => _alphabet;
10 |
11 | public override byte[] Decode(string input) => Decode(input, true, true);
12 |
13 | public override string Encode(byte[] bytes) => Encode(bytes, true, true);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base64.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Multiformats.Base
4 | {
5 | internal abstract class Base64 : Multibase
6 | {
7 | private static string Pad(string input)
8 | {
9 | var diff = input.Length % 4;
10 |
11 | return diff > 0 ? input + new string('=', 4 - diff) : input;
12 | }
13 |
14 | protected string Encode(byte[] input, bool urlSafe, bool padded)
15 | {
16 | var result = Convert.ToBase64String(input);
17 | if (urlSafe)
18 | result = result.Replace('+', '-').Replace('/', '_');
19 |
20 | if (!padded)
21 | result = result.TrimEnd('=');
22 |
23 | return result;
24 | }
25 |
26 | protected byte[] Decode(string input, bool urlSafe, bool padded)
27 | {
28 | if (urlSafe)
29 | input = input.Replace('-', '+').Replace('_', '/');
30 |
31 | input = Pad(input.TrimEnd('='));
32 |
33 | return Convert.FromBase64String(input);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Base8.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Multiformats.Base
6 | {
7 | internal class Base8 : Multibase
8 | {
9 | private static readonly char[] _alphabet = {'0', '1', '2', '3', '4', '5', '6', '7'};
10 |
11 | protected override string Name => "base8";
12 | protected override char Prefix => '7';
13 | protected override char[] Alphabet => _alphabet;
14 |
15 | private static byte[] FromOct(byte o) => new[] { (byte)(o >> 2), (byte)((o >> 1) & 1), (byte)(o & 1) };
16 | private static byte ToNum8(char c) => Convert.ToByte($"{c}", 8);
17 | private static char FromBit(byte b) => b == 0 ? '0' : '1';
18 |
19 | public override byte[] Decode(string input)
20 | {
21 | var base2 = _bases[MultibaseEncoding.Base2];
22 |
23 | var bin = input.Select(ToNum8).SelectMany(FromOct).Select(FromBit);
24 |
25 | var modlen = input.Length % 8;
26 |
27 | var binstr = "";
28 | if (modlen == 0)
29 | binstr = new string(bin.ToArray());
30 | else if (modlen == 3)
31 | binstr = new string(bin.Skip(1).ToArray());
32 | else if (modlen == 6)
33 | binstr = new string(bin.Skip(2).ToArray());
34 |
35 | return base2.Decode(binstr);
36 | }
37 |
38 | private static byte ToBit(char c) => c == '0' ? (byte)0 : (byte)1;
39 | private static byte ToOct(IEnumerable b)
40 | {
41 | var bin = b.ToArray();
42 |
43 | return (byte)((bin[0] << 2) | (bin[1] << 1) | bin[2]);
44 | }
45 | private static char FromNum8(byte b) => Convert.ToString(b, 8).First();
46 |
47 | private static IEnumerable BinToOct(IEnumerable b)
48 | {
49 | var result = new List();
50 | var batch = new List();
51 | foreach (var x in b)
52 | {
53 | batch.Add(x);
54 |
55 | if (batch.Count == 3)
56 | {
57 | result.Add(ToOct(batch));
58 | batch.Clear();
59 | }
60 | }
61 |
62 | return result;
63 | }
64 |
65 | public override string Encode(byte[] bytes)
66 | {
67 | var base2 = _bases[MultibaseEncoding.Base2];
68 | var encoded = base2.Encode(bytes);
69 | var modlen = encoded.Length % 3;
70 | var prepad = new string('0', modlen == 0 ? 0 : 3 - modlen);
71 |
72 | return new string(BinToOct((prepad + encoded).Select(ToBit)).Select(FromNum8).ToArray());
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Identity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace Multiformats.Base
5 | {
6 | internal class Identity : Multibase
7 | {
8 | protected override string Name => "identity";
9 | protected override char Prefix => '\0';
10 | protected override char[] Alphabet => Array.Empty();
11 |
12 | protected override bool IsValid(string value) => true;
13 | public override byte[] Decode(string input) => input.Select(Convert.ToByte).ToArray();
14 | public override string Encode(byte[] bytes) => new string(bytes.Select(Convert.ToChar).ToArray());
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/LetterCasing.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | internal enum LetterCasing
4 | {
5 | Ignore,
6 | Lower,
7 | Upper
8 | }
9 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Multibase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace Multiformats.Base
6 | {
7 | public abstract class Multibase
8 | {
9 | protected static readonly Dictionary _bases;
10 |
11 | static Multibase()
12 | {
13 | _bases = new Dictionary
14 | {
15 | {MultibaseEncoding.Identity, new Identity()},
16 | {MultibaseEncoding.Base2, new Base2()},
17 | {MultibaseEncoding.Base8, new Base8()},
18 | {MultibaseEncoding.Base10, new Base10()},
19 | {MultibaseEncoding.Base16Lower, new Base16Lower()},
20 | {MultibaseEncoding.Base16Upper, new Base16Upper()},
21 | {MultibaseEncoding.Base32Lower, new Base32Lower()},
22 | {MultibaseEncoding.Base32Upper, new Base32Upper()},
23 | {MultibaseEncoding.Base32PaddedLower, new Base32PaddedLower()},
24 | {MultibaseEncoding.Base32PaddedUpper, new Base32PaddedUpper()},
25 | {MultibaseEncoding.Base32HexLower, new Base32HexLower()},
26 | {MultibaseEncoding.Base32HexUpper, new Base32HexUpper()},
27 | {MultibaseEncoding.Base32HexPaddedLower, new Base32HexPaddedLower()},
28 | {MultibaseEncoding.Base32HexPaddedUpper, new Base32HexPaddedUpper()},
29 | {MultibaseEncoding.Base32Z, new Base32Z()},
30 | {MultibaseEncoding.Base58Btc, new Base58Btc()},
31 | {MultibaseEncoding.Base58Flickr, new Base58Flickr()},
32 | {MultibaseEncoding.Base64, new Base64Normal()},
33 | {MultibaseEncoding.Base64Padded, new Base64Padded()},
34 | {MultibaseEncoding.Base64Url, new Base64Url()},
35 | {MultibaseEncoding.Base64UrlPadded, new Base64UrlPadded()},
36 | };
37 | }
38 |
39 | public static Multibase Base2 => _bases[MultibaseEncoding.Base2];
40 | public static Multibase Base8 => _bases[MultibaseEncoding.Base8];
41 | public static Multibase Base10 => _bases[MultibaseEncoding.Base10];
42 | public static Multibase Base16 => _bases[MultibaseEncoding.Base16Lower];
43 | public static Multibase Base32 => _bases[MultibaseEncoding.Base32Lower];
44 | public static Multibase Base58 => _bases[MultibaseEncoding.Base58Btc];
45 | public static Multibase Base64 => _bases[MultibaseEncoding.Base64];
46 |
47 | protected abstract string Name { get; }
48 | protected abstract char Prefix { get; }
49 | protected abstract char[] Alphabet { get; }
50 | protected virtual bool IsValid(string value) => value.Distinct().All(c => Array.IndexOf(Alphabet, c) > -1);
51 |
52 | public abstract byte[] Decode(string input);
53 | public abstract string Encode(byte[] bytes);
54 |
55 | ///
56 | /// Encode a byte array to multibase given encoding.
57 | ///
58 | /// Encoding
59 | /// Bytes
60 | /// Encoded string
61 | public static string Encode(MultibaseEncoding encoding, byte[] bytes)
62 | {
63 | if (!_bases.TryGetValue(encoding, out var @base))
64 | throw new NotSupportedException($"{encoding} is not supported.");
65 |
66 | return Encode(@base, bytes, true);
67 | }
68 |
69 | ///
70 | /// Encode a byte array to multibase given encoding in string format.
71 | ///
72 | /// Encoding
73 | /// Bytes
74 | /// Encoded string
75 | public static string Encode(string encoding, byte[] bytes)
76 | {
77 | var @base = _bases.Values.SingleOrDefault(b => b.Name.Equals(encoding));
78 | if (@base == null)
79 | throw new NotSupportedException($"{encoding} is not supported.");
80 |
81 | return Encode(@base, bytes, true);
82 | }
83 |
84 | private static string Encode(Multibase @base, byte[] bytes, bool prefix)
85 | {
86 | if (bytes == null || bytes.Length == 0)
87 | throw new ArgumentNullException(nameof(bytes));
88 |
89 | return prefix ? @base.Prefix + @base.Encode(bytes) : @base.Encode(bytes);
90 | }
91 |
92 | ///
93 | /// Encode a byte array given encoding (without multibase prefix).
94 | ///
95 | /// Encoding
96 | /// Bytes
97 | /// Encoded string
98 | public static string EncodeRaw(MultibaseEncoding encoding, byte[] bytes)
99 | {
100 | var @base = _bases[encoding];
101 | if (@base == null)
102 | throw new NotSupportedException($"{encoding} is not supported.");
103 |
104 | return Encode(@base, bytes, false);
105 | }
106 |
107 | ///
108 | /// Decode an multibase encoded string.
109 | ///
110 | /// Encoded string
111 | /// Encoding used
112 | /// Don't allow non-valid characters for given encoding
113 | /// Bytes
114 | public static byte[] Decode(string input, out MultibaseEncoding encoding, bool strict = true)
115 | {
116 | if (string.IsNullOrEmpty(input))
117 | throw new ArgumentNullException(nameof(input));
118 |
119 | var @base = _bases.Values.SingleOrDefault(b => b.Prefix == input[0]);
120 | if (@base == null)
121 | throw new NotSupportedException($"{input[0]} is an unknown encoding prefix.");
122 |
123 | var value = input.Substring(1);
124 | encoding = _bases.SingleOrDefault(kv => kv.Value.Equals(@base)).Key;
125 |
126 | if (strict && !@base.IsValid(value))
127 | throw new InvalidOperationException($"{value} contains invalid chars for {encoding}.");
128 |
129 | return @base.Decode(value);
130 | }
131 |
132 | ///
133 | /// Decode an multibase encoded string.
134 | ///
135 | /// Encoded string
136 | /// Encoding used
137 | /// Don't allow non-valid characters for given encoding
138 | /// Bytes
139 | public static byte[] Decode(string input, out string encoding, bool strict = true)
140 | {
141 | if (string.IsNullOrEmpty(input))
142 | throw new ArgumentNullException(nameof(input));
143 |
144 | var @base = _bases.Values.SingleOrDefault(b => b.Prefix == input[0]);
145 | if (@base == null)
146 | throw new NotSupportedException($"{input[0]} is an unknown encoding prefix.");
147 |
148 | var value = input.Substring(1);
149 | encoding = @base.Name;
150 |
151 | if (strict && !@base.IsValid(value))
152 | throw new InvalidOperationException($"{value} contains invalid chars for {encoding}.");
153 |
154 | return @base.Decode(value);
155 | }
156 |
157 | ///
158 | /// Decode an encoded string using given encoded (without multibase prefix).
159 | ///
160 | /// Encoding
161 | /// Encoded string
162 | /// Bytes
163 | public static byte[] DecodeRaw(MultibaseEncoding encoding, string input)
164 | {
165 | if (string.IsNullOrEmpty(input))
166 | throw new ArgumentNullException(nameof(input));
167 |
168 | if (!_bases.TryGetValue(encoding, out var @base))
169 | throw new NotSupportedException($"{encoding} is an unknown encoding.");
170 |
171 | return @base.Decode(input);
172 | }
173 |
174 | ///
175 | /// Try to decode an encoded string. If prefixed with a multibase prefix it's guaranteed to give the correct value, if not there's no guarantee it will pick the right encoding.
176 | ///
177 | /// Encoded string
178 | /// Guessed encoding
179 | /// Decoded bytes
180 | /// True on success (no guarantee it's correct), false on error
181 | public static bool TryDecode(string input, out MultibaseEncoding encoding, out byte[] bytes)
182 | {
183 | try
184 | {
185 | // special case for base2 without prefix
186 | if (input[0] == '0' && input.Length % 8 == 0)
187 | throw new Exception();
188 |
189 | bytes = Decode(input, out encoding);
190 | return true;
191 | }
192 | catch
193 | {
194 | foreach (var @base in _bases.Values.Skip(1).Where(b => b.IsValid(input)))
195 | {
196 | try
197 | {
198 | bytes = @base.Decode(input);
199 | encoding = _bases.SingleOrDefault(kv => kv.Value.Equals(@base)).Key;
200 | return true;
201 | }
202 | catch
203 | {
204 | }
205 | }
206 | }
207 |
208 | encoding = default(MultibaseEncoding);
209 | bytes = null;
210 | return false;
211 | }
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/src/Multiformats.Base/MultibaseEncoding.cs:
--------------------------------------------------------------------------------
1 | namespace Multiformats.Base
2 | {
3 | public enum MultibaseEncoding
4 | {
5 | Identity,
6 | Base2,
7 | Base8,
8 | Base10,
9 | Base16Lower,
10 | Base16Upper,
11 | Base32Lower,
12 | Base32Upper,
13 | Base32PaddedLower,
14 | Base32PaddedUpper,
15 | Base32Z,
16 | Base32HexLower,
17 | Base32HexUpper,
18 | Base32HexPaddedLower,
19 | Base32HexPaddedUpper,
20 | Base58Btc,
21 | Base58Flickr,
22 | Base64,
23 | Base64Padded,
24 | Base64Url,
25 | Base64UrlPadded
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Multiformats.Base/Multiformats.Base.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Multiformat base encodings
5 | Copyright © tabrath 2018
6 | Multiformats.Base
7 | 2.0.2
8 | tabrath
9 | net461;netstandard1.6;netstandard2.0;
10 | true
11 | Multiformats.Base
12 | Multiformats.Base
13 | multiformats multibase base2 base8 base10 base16 base32 base58 base64 z-base32
14 | https://cdn.rawgit.com/multiformats/website/116894f6/favicon.png
15 | https://github.com/multiformats/cs-multibase/blob/master/LICENSE
16 | git
17 | https://github.com/multiformats/cs-multibase
18 | $(PackageTargetFallback);netstandard;portable-net461+win8
19 | 1.6.1
20 | true
21 |
22 |
23 |
24 | true
25 | portable
26 | false
27 | $(DefineConstants);DEBUG
28 |
29 |
30 | portable
31 | true
32 | $(DefineConstants)
33 |
34 |
35 |
36 |
37 | true
38 |
39 | false
40 |
41 | true
42 | snupkg
43 | .pdb;$(AllowedOutputExtensionsInPackageBuildOutputFolder)
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | all
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/test/Multiformats.Base.Tests/MultibaseTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Xunit;
9 | using Xunit.Sdk;
10 |
11 | namespace Multiformats.Base.Tests
12 | {
13 | public class MultibaseTests
14 | {
15 | [Fact]
16 | public void Decode_GivenInvalidChars_ThrowsInvalidOperationException()
17 | {
18 | // prefix 0 - base2
19 | // value 99 - invalid chars
20 |
21 | Assert.Throws(() => Multibase.Decode("099", out string _));
22 | }
23 |
24 | [Theory]
25 | [InlineData("")]
26 | [InlineData(null)]
27 | public void Decode_GivenEmptyInput_ThrowsArgumentNullException(string value)
28 | {
29 | Assert.Throws(() => Multibase.Decode(value, out string _));
30 | }
31 |
32 | [Fact]
33 | public void Decode_GivenUnknownPrefix_ThrowsUnsupportedException()
34 | {
35 | Assert.Throws(() => Multibase.Decode("ø", out string _));
36 | }
37 |
38 | [Fact]
39 | public void DecodeRaw_GivenUnknownEncoding_ThrowsUnsupportedException()
40 | {
41 | Assert.Throws(() => Multibase.DecodeRaw((MultibaseEncoding)0x2000, "abab"));
42 | }
43 |
44 | [Theory]
45 | [InlineData("")]
46 | [InlineData(null)]
47 | public void DecodeRaw_GivenEmptyInput_ThrowsArgumentNullException(string value)
48 | {
49 | Assert.Throws(() => Multibase.DecodeRaw(MultibaseEncoding.Identity, value));
50 | }
51 |
52 | [Fact]
53 | public void Encode_GivenEmptyBytes_ThrowsArgumentNullException()
54 | {
55 | Assert.Throws(() => Multibase.Encode(MultibaseEncoding.Base2, new byte[] { }));
56 | }
57 |
58 | [Fact]
59 | public void Encode_GivenNullBytes_ThrowsArgumentNullException()
60 | {
61 | Assert.Throws(() => Multibase.Encode(MultibaseEncoding.Base2, null));
62 | }
63 |
64 | [Fact]
65 | public void Encode_GivenUnknownEncoding_ThrowsUnsupportedException()
66 | {
67 | Assert.Throws(() => Multibase.Encode((MultibaseEncoding)0x2000, new byte[] { 0, 1, 2, 3 }));
68 | }
69 |
70 | [Theory]
71 | [InlineData(MultibaseEncoding.Identity)]
72 | [InlineData(MultibaseEncoding.Base2)]
73 | [InlineData(MultibaseEncoding.Base8)]
74 | [InlineData(MultibaseEncoding.Base10)]
75 | [InlineData(MultibaseEncoding.Base16Lower)]
76 | [InlineData(MultibaseEncoding.Base16Upper)]
77 | [InlineData(MultibaseEncoding.Base32Lower)]
78 | [InlineData(MultibaseEncoding.Base32Upper)]
79 | [InlineData(MultibaseEncoding.Base32PaddedLower)]
80 | [InlineData(MultibaseEncoding.Base32PaddedUpper)]
81 | [InlineData(MultibaseEncoding.Base32HexLower)]
82 | [InlineData(MultibaseEncoding.Base32HexUpper)]
83 | [InlineData(MultibaseEncoding.Base32HexPaddedLower)]
84 | [InlineData(MultibaseEncoding.Base32HexPaddedUpper)]
85 | [InlineData(MultibaseEncoding.Base58Btc)]
86 | [InlineData(MultibaseEncoding.Base58Flickr)]
87 | [InlineData(MultibaseEncoding.Base64)]
88 | [InlineData(MultibaseEncoding.Base64Padded)]
89 | [InlineData(MultibaseEncoding.Base64Url)]
90 | [InlineData(MultibaseEncoding.Base64UrlPadded)]
91 | public void TestRoundTrip(MultibaseEncoding encoding)
92 | {
93 | var rand = new Random(Environment.TickCount);
94 | var buf = new byte[rand.Next(16, 256)];
95 | rand.NextBytes(buf);
96 |
97 | var encoded = Multibase.EncodeRaw(encoding, buf);
98 | var decoded = Multibase.DecodeRaw(encoding, encoded);
99 |
100 | Assert.Equal(decoded, buf);
101 | }
102 |
103 | [Theory]
104 | [InlineData(MultibaseEncoding.Identity)]
105 | [InlineData(MultibaseEncoding.Base2)]
106 | [InlineData(MultibaseEncoding.Base8)]
107 | [InlineData(MultibaseEncoding.Base10)]
108 | [InlineData(MultibaseEncoding.Base16Lower)]
109 | [InlineData(MultibaseEncoding.Base16Upper)]
110 | [InlineData(MultibaseEncoding.Base32Lower)]
111 | [InlineData(MultibaseEncoding.Base32Upper)]
112 | [InlineData(MultibaseEncoding.Base32PaddedLower)]
113 | [InlineData(MultibaseEncoding.Base32PaddedUpper)]
114 | [InlineData(MultibaseEncoding.Base32HexLower)]
115 | [InlineData(MultibaseEncoding.Base32HexUpper)]
116 | [InlineData(MultibaseEncoding.Base32HexPaddedLower)]
117 | [InlineData(MultibaseEncoding.Base32HexPaddedUpper)]
118 | [InlineData(MultibaseEncoding.Base58Btc)]
119 | [InlineData(MultibaseEncoding.Base58Flickr)]
120 | [InlineData(MultibaseEncoding.Base64)]
121 | [InlineData(MultibaseEncoding.Base64Padded)]
122 | [InlineData(MultibaseEncoding.Base64Url)]
123 | [InlineData(MultibaseEncoding.Base64UrlPadded)]
124 | public void TestRoundTripRaw(MultibaseEncoding encoding)
125 | {
126 | var rand = new Random(Environment.TickCount);
127 | var buf = new byte[rand.Next(16, 256)];
128 | rand.NextBytes(buf);
129 |
130 | var encoded = Multibase.Encode(encoding, buf);
131 | var decoded = Multibase.Decode(encoded, out MultibaseEncoding decodedEncoding);
132 |
133 | Assert.Equal(encoding, decodedEncoding);
134 | Assert.Equal(decoded, buf);
135 | }
136 |
137 | [Theory]
138 | [InlineData("001000100011001010110001101100101011011100111010001110010011000010110110001101001011110100110010100100000011001010111011001100101011100100111100101110100011010000110100101101110011001110010000100100001", MultibaseEncoding.Base2)]
139 | [InlineData("71043126154533472162302661513646244031273145344745643206455631620441", MultibaseEncoding.Base8)]
140 | [InlineData("f446563656e7472616c697a652065766572797468696e672121", MultibaseEncoding.Base16Lower)]
141 | [InlineData("F446563656E7472616C697A652065766572797468696E672121", MultibaseEncoding.Base16Upper)]
142 | [InlineData("birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb", MultibaseEncoding.Base32Lower)]
143 | [InlineData("BIRSWGZLOORZGC3DJPJSSAZLWMVZHS5DINFXGOIJB", MultibaseEncoding.Base32Upper)]
144 | [InlineData("v8him6pbeehp62r39f9ii0pbmclp7it38d5n6e891", MultibaseEncoding.Base32HexLower)]
145 | [InlineData("V8HIM6PBEEHP62R39F9II0PBMCLP7IT38D5N6E891", MultibaseEncoding.Base32HexUpper)]
146 | [InlineData("cirswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb", MultibaseEncoding.Base32PaddedLower)]
147 | [InlineData("CIRSWGZLOORZGC3DJPJSSAZLWMVZHS5DINFXGOIJB", MultibaseEncoding.Base32PaddedUpper)]
148 | [InlineData("t8him6pbeehp62r39f9ii0pbmclp7it38d5n6e891", MultibaseEncoding.Base32HexPaddedLower)]
149 | [InlineData("T8HIM6PBEEHP62R39F9II0PBMCLP7IT38D5N6E891", MultibaseEncoding.Base32HexPaddedUpper)]
150 | [InlineData("het1sg3mqqt3gn5djxj11y3msci3817depfzgqejb", MultibaseEncoding.Base32Z)]
151 | [InlineData("Ztwe7gVTeK8wswS1gf8hrgAua9fcw9reboD", MultibaseEncoding.Base58Flickr)]
152 | [InlineData("zUXE7GvtEk8XTXs1GF8HSGbVA9FCX9SEBPe", MultibaseEncoding.Base58Btc)]
153 | [InlineData("mRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchIQ", MultibaseEncoding.Base64)]
154 | [InlineData("MRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchIQ==", MultibaseEncoding.Base64Padded)]
155 | [InlineData("uRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchIQ", MultibaseEncoding.Base64Url)]
156 | [InlineData("URGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchIQ==", MultibaseEncoding.Base64UrlPadded)]
157 | public void TestTryDecoding_GivenValidEncodedInput_Prefixed(string input, MultibaseEncoding encoding)
158 | {
159 | var expected = "Decentralize everything!!";
160 | var result = Multibase.TryDecode(input, out var decodedEncoding, out var decodedBytes);
161 |
162 | Assert.True(result);
163 | Assert.Equal(encoding, decodedEncoding);
164 | Assert.Equal(expected, Encoding.UTF8.GetString(decodedBytes));
165 | }
166 |
167 | [Theory]
168 | [InlineData("01000100011001010110001101100101011011100111010001110010011000010110110001101001011110100110010100100000011001010111011001100101011100100111100101110100011010000110100101101110011001110010000100100001", MultibaseEncoding.Base2)]
169 | [InlineData("1043126154533472162302661513646244031273145344745643206455631620441", MultibaseEncoding.Base8)]
170 | [InlineData("446563656e7472616c697a652065766572797468696e672121", MultibaseEncoding.Base16Lower)]
171 | [InlineData("446563656E7472616C697A652065766572797468696E672121", MultibaseEncoding.Base16Upper)]
172 | [InlineData("irswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb", MultibaseEncoding.Base32Lower)]
173 | [InlineData("IRSWGZLOORZGC3DJPJSSAZLWMVZHS5DINFXGOIJB", MultibaseEncoding.Base32Upper)]
174 | [InlineData("8him6pbeehp62r39f9ii0pbmclp7it38d5n6e891", MultibaseEncoding.Base32HexLower)]
175 | [InlineData("8HIM6PBEEHP62R39F9II0PBMCLP7IT38D5N6E891", MultibaseEncoding.Base32HexUpper)]
176 | [InlineData("et1sg3mqqt3gn5djxj11y3msci3817depfzgqejb", MultibaseEncoding.Base32Z)]
177 | [InlineData("RGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchIQ==", MultibaseEncoding.Base64Padded)]
178 | public void TestTryDecoding_GivenValidEncodedInput_Unprefixed(string input, MultibaseEncoding encoding)
179 | {
180 | var expected = "Decentralize everything!!";
181 | var result = Multibase.TryDecode(input, out var decodedEncoding, out var decodedBytes);
182 |
183 | Assert.True(result);
184 | Assert.Equal(encoding, decodedEncoding);
185 | Assert.Equal(expected, Encoding.UTF8.GetString(decodedBytes));
186 | }
187 |
188 | // Official test vectors
189 | private static void TestVector(string encoding, string encoded, string expected)
190 | {
191 | var decoded = Multibase.Decode(encoded, out string mbEncoding);
192 |
193 | Assert.Equal(encoding, mbEncoding);
194 | Assert.Equal(expected, Encoding.UTF8.GetString(decoded));
195 |
196 | var rencoded = Multibase.Encode(mbEncoding, decoded);
197 |
198 | Assert.Equal(encoded, rencoded);
199 | }
200 |
201 | [Theory]
202 | [CsvData("test1.csv")]
203 | public void TestVector_1(string encoding, string encoded)
204 | {
205 | var expected = "Decentralize everything!!";
206 |
207 | TestVector(encoding, encoded, expected);
208 | }
209 |
210 | [Theory]
211 | [CsvData("test2.csv")]
212 | public void TestVector_2(string encoding, string encoded)
213 | {
214 | var expected = "yes mani !";
215 |
216 | TestVector(encoding, encoded, expected);
217 | }
218 |
219 | [Theory]
220 | [CsvData("test3.csv")]
221 | public void TestVector_3(string encoding, string encoded)
222 | {
223 | var expected = "hello world";
224 |
225 | TestVector(encoding, encoded, expected);
226 | }
227 |
228 | [Theory]
229 | [CsvData("test4.csv")]
230 | public void TestVector_4(string encoding, string encoded)
231 | {
232 | var expected = "\x00yes mani !";
233 |
234 | TestVector(encoding, encoded, expected);
235 | }
236 |
237 | [Theory]
238 | [CsvData("test5.csv")]
239 | public void TestVector_5(string encoding, string encoded)
240 | {
241 | var expected = "\x00\x00yes mani !";
242 |
243 | TestVector(encoding, encoded, expected);
244 | }
245 |
246 | [Theory]
247 | [CsvData("test6.csv")]
248 | public void TestVector_6(string encoding, string encoded)
249 | {
250 | var expected = "hello world";
251 |
252 | var decoded = Multibase.Decode(encoded, out string mbEncoding, false);
253 |
254 | Assert.Equal(encoding, mbEncoding);
255 | Assert.Equal(expected, Encoding.UTF8.GetString(decoded));
256 | }
257 |
258 | [Fact]
259 | public async Task TestBase58ConcurrentDecoding()
260 | {
261 | var tasks = Enumerable.Range(1, 10).Select(_ => Task.Run(() =>
262 | {
263 | var success = Multibase.TryDecode("Z6BLZQNPgws5ahFtr8x", out var encoding, out var bytes);
264 | Assert.True(success);
265 | Assert.Equal(MultibaseEncoding.Base58Flickr, encoding);
266 | Assert.Equal("Concurrency !", Encoding.UTF8.GetString(bytes, 0, bytes.Length));
267 | }));
268 | await Task.WhenAll(tasks);
269 | }
270 | }
271 |
272 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
273 | public class CsvDataAttribute : DataAttribute
274 | {
275 | private readonly string _fileName;
276 | public CsvDataAttribute(string fileName)
277 | {
278 | _fileName = fileName;
279 | }
280 |
281 | public override IEnumerable