diff --git a/src/DividingCoder.cs b/src/DividingCoder.cs index 1399b72..ffd4f27 100644 --- a/src/DividingCoder.cs +++ b/src/DividingCoder.cs @@ -23,7 +23,7 @@ public abstract class DividingCoder(TAlphabet alphabet) : IBaseCoder, INonAllocatingBaseCoder where TAlphabet: CodingAlphabet { - readonly int reductionFactor = Convert.ToInt32(1000 * Math.Log2(alphabet.Length) / 8); + readonly int reductionFactor = Convert.ToInt32(10_000 * Math.Log2(alphabet.Length) / 8); readonly char zeroChar = alphabet.Value[0]; /// @@ -40,7 +40,7 @@ public virtual int GetSafeByteCountForDecoding(ReadOnlySpan text) [MethodImpl(MethodImplOptions.AggressiveInlining)] int getSafeByteCountForDecoding(int textLen, int zeroPrefixLen) { - return zeroPrefixLen + ((textLen - zeroPrefixLen) * reductionFactor / 1000) + 1; + return zeroPrefixLen + ((textLen - zeroPrefixLen) * reductionFactor / 10_000) + 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -62,7 +62,7 @@ public virtual int GetSafeCharCountForEncoding(ReadOnlySpan bytes) [MethodImpl(MethodImplOptions.AggressiveInlining)] int getSafeCharCountForEncoding(int bytesLen, int zeroPrefixLen) { - return zeroPrefixLen + ((bytesLen - zeroPrefixLen) * 1000 / reductionFactor) + 1; + return zeroPrefixLen + ((bytesLen - zeroPrefixLen) * 10_000 / reductionFactor) + 1; } /// diff --git a/test/Base62/DefaultTest.cs b/test/Base62/DefaultTest.cs index 20143ef..159ea09 100644 --- a/test/Base62/DefaultTest.cs +++ b/test/Base62/DefaultTest.cs @@ -61,5 +61,20 @@ public void TryDecode_ReturnsCorrectValues(string decoded, string encoded) Assert.That(result, Is.True); Assert.That(Encoding.UTF8.GetString(output[..bytesWritten]), Is.EqualTo(decoded)); } - + + [Test] + public void Roundtrip_DoesNotTruncateHighByte() + { + // https://github.com/ssg/SimpleBase/issues/79 + + // 2762 is the smallest length where (textLen * 744 / 1000) + 1 underestimates + // the required output buffer by 1, dropping the most-significant byte. + var bytes = new byte[2762]; + Array.Fill(bytes, (byte)0xFF); + + var encoded = Base62.Default.Encode(bytes); + var decoded = Base62.Default.Decode(encoded); + + Assert.That(decoded, Is.EqualTo(bytes)); + } }