Skip to content

Commit

Permalink
Merge pull request #10 from DJGosnell/master
Browse files Browse the repository at this point in the history
Fix for Issue #4
  • Loading branch information
ghost1face authored Sep 14, 2022
2 parents a14a489 + eb9a595 commit ea91bf8
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
10 changes: 10 additions & 0 deletions Base62.Tests/Base62Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ public void ASCII_AND_UTF8_Can_RoundTrip(string input, string expected)
Assert.Equal(input, decoded);
}

[Fact]
public void FirstZeroBytesAreConvertedCorrectly()
{
var sourceBytes = new byte[] { 0, 0, 1, 2, 0, 0 };
var encoded = Base62Converter.BaseConvert(sourceBytes, 256, 62);
var decoded = Base62Converter.BaseConvert(encoded, 62, 256);
Assert.Equal(sourceBytes, decoded);

}

public static IEnumerable<object[]> GetData()
{
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "validation_data.txt");
Expand Down
6 changes: 6 additions & 0 deletions Base62/Base62.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
</None>
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>Base62.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

<PropertyGroup Condition="$(Configuration) == 'Release'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
Expand Down
46 changes: 40 additions & 6 deletions Base62/Base62Converter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Text;

namespace Base62
Expand Down Expand Up @@ -86,15 +87,46 @@ public byte[] Decode(byte[] value)
return BaseConvert(value, 62, 256);
}

private static byte[] BaseConvert(byte[] source, int sourceBase, int targetBase)
/// <summary>
/// Converts source byte array from the source base to the destination base.
/// </summary>
/// <param name="source">Byte array to convert.</param>
/// <param name="sourceBase">Source base to convert from.</param>
/// <param name="targetBase">Target base to convert to.</param>
/// <returns>Converted byte array.</returns>
internal static byte[] BaseConvert(byte[] source, int sourceBase, int targetBase)
{
var result = new List<int>();
if (targetBase < 2 || targetBase > 256)
throw new ArgumentOutOfRangeException(nameof(targetBase), targetBase, "Value must be between 2 & 256 (inclusive)");

if (sourceBase < 2 || sourceBase > 256)
throw new ArgumentOutOfRangeException(nameof(sourceBase), sourceBase, "Value must be between 2 & 256 (inclusive)");

// Set initial capacity estimate if the size is small.
var startCapacity = source.Length < 1028
? (int)(source.Length * 1.5)
: source.Length;

var result = new List<int>(startCapacity);
var quotient = new List<byte>((int)(source.Length * 0.5));
int count;
int initialStartOffset = 0;

// This is a bug fix for the following issue:
// https://github.com/ghost1face/base62/issues/4
while (source[initialStartOffset] == 0)
{
result.Add(0);
initialStartOffset++;
}

int startOffset = initialStartOffset;

while ((count = source.Length) > 0)
{
var quotient = new List<byte>();
quotient.Clear();
int remainder = 0;
for (var i = 0; i != count; i++)
for (var i = initialStartOffset; i != count; i++)
{
int accumulator = source[i] + remainder * sourceBase;
byte digit = (byte)((accumulator - (accumulator % targetBase)) / targetBase);
Expand All @@ -105,11 +137,13 @@ private static byte[] BaseConvert(byte[] source, int sourceBase, int targetBase)
}
}

result.Insert(0, remainder);
result.Insert(startOffset, remainder);
source = quotient.ToArray();
initialStartOffset = 0;
}

var output = new byte[result.Count];

for (int i = 0; i < result.Count; i++)
output[i] = (byte)result[i];

Expand Down

0 comments on commit ea91bf8

Please sign in to comment.