Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Base64 URL Safe Data Encoder #1096

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions NBitcoin.Tests/ConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ public class ConverterTests
[Trait("UnitTest", "UnitTest")]
public void CanConvertText()
{
string testPhrase = "é ^ç hello \"12345\" wooorld";
var testPhrase = Encoding.UTF8.GetBytes("é ^ç hello \"12345\" wooorld");
var rfc4648_1 = new byte[] { 0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e };
var rfc4648_2 = new byte[] { 0x14, 0xfb, 0x9c, 0x03, 0xd9 };
var rfc4648_3 = new byte[] { 0x14, 0xfb, 0x9c, 0x03 };


var tests = new[]
{
new
Expand Down Expand Up @@ -43,6 +48,31 @@ public void CanConvertText()
Input = testPhrase,
Expected = "w6kgXsOnIGhlbGxvICIxMjM0NSIgIHdvb29ybGQ="
},
new
{
Encoder = Encoders.Base64UrlSafe,
Input = testPhrase,
Expected = "w6kgXsOnIGhlbGxvICIxMjM0NSIgIHdvb29ybGQ"
},
new
{
Encoder = Encoders.Base64UrlSafe,
Input = rfc4648_1,
Expected = "FPucA9l-"
},
new
{
Encoder = Encoders.Base64UrlSafe,
Input = rfc4648_2,
Expected = "FPucA9k"
},
new
{
Encoder = Encoders.Base64UrlSafe,
Input = rfc4648_3,
Expected = "FPucAw"
},

//Not yet implemented
//new
//{
Expand Down Expand Up @@ -89,14 +119,13 @@ public void CanConvertText()

foreach (var test in tests)
{
var input = Encoding.UTF8.GetBytes(test.Input);
var encoded = test.Encoder.EncodeData(input);
var encoded = test.Encoder.EncodeData(test.Input);
Assert.Equal(test.Expected, encoded);

try
{
var decoded = test.Encoder.DecodeData(encoded);
AssertEx.CollectionEquals(input, decoded);
AssertEx.CollectionEquals(test.Input, decoded);
}
catch (NotSupportedException)
{
Expand Down
30 changes: 30 additions & 0 deletions NBitcoin/DataEncoders/Base64UrlSafeEncoder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Linq;

namespace NBitcoin.DataEncoders
{
public class Base64UrlSafeEncoder : DataEncoder
{
static readonly char[] padding = { '=' };
static readonly int paddingBoundary = 4;
public override byte[] DecodeData(string encoded)
{
var temp = encoded.Replace('-', '+').Replace('_', '/');

// Re-add padding if necessary
var remaining = temp.Length % paddingBoundary;
switch(remaining) {
case 2:
case 3:
temp += string.Concat(Enumerable.Repeat('=', paddingBoundary-remaining));
break;
}
return Convert.FromBase64String(temp);
}

public override string EncodeData(byte[] data, int offset, int count)
{
return Convert.ToBase64String(data, offset, count).Replace('+', '-').Replace('/', '_').TrimEnd(padding);
}
}
}
9 changes: 9 additions & 0 deletions NBitcoin/DataEncoders/Encoders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ public static DataEncoder Base64
}
}

static readonly Base64UrlSafeEncoder _Base64UrlSafe = new Base64UrlSafeEncoder();
public static DataEncoder Base64UrlSafe
{
get
{
return _Base64UrlSafe;
}
}

public static Bech32Encoder Bech32(string hrp)
{
return new Bech32Encoder(hrp);
Expand Down