If you know the byte length you want encoded, you could do this instead:
Options[Base58Encode] = {n -> None};
Base58Encode[x_Integer, OptionsPattern[]] :=
StringJoin[
StringTake[
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
Partition[
1 + If[OptionValue[n] === None, IntegerDigits[x, 58],
IntegerDigits[x, 58, Ceiling[OptionValue[n]*8/Log[2, 58]]]],
1]]]
and test with
byteLength = 16;
i = RandomInteger[2^(8*byteLength), 100];
i = Join[i, {0, 2^(8*byteLength) - 1}];
{Base58Encode[#], Base58Encode[#, n -> byteLength]} & /@
Sort[i] // TableForm
The first column doesn't define a byte length and the second does. In the second column, you always get the "right" amount of leading '1s', even if you get a value that would normally result in too few '1s'
BTW, this is the only thread I have been reading. I found my own mistake this morning when I was doing the RIPEMD-160 in Mathematica. I started that before I saw your post above. My code is very similar to yours, with minor differences:
f[j_Integer /; 0 < j <= 16, x_Integer, y_Integer, z_Integer] :=
BitXor[x, y, z];
f[j_Integer /; 16 < j <= 32, x_Integer, y_Integer, z_Integer] :=
BitOr[BitAnd[x, y], BitAnd[BitNot[x], z]];
f[j_Integer /; 32 < j <= 48, x_Integer, y_Integer, z_Integer] :=
BitXor[BitOr[x, BitNot[y]], z];
f[j_Integer /; 48 < j <= 64, x_Integer, y_Integer, z_Integer] :=
BitOr[BitAnd[x, z], BitAnd[y, BitNot[z]]];
f[j_Integer /; 64 < j <= 80, x_Integer, y_Integer, z_Integer] :=
BitXor[x, BitOr[y, BitNot[z]]];
k = Flatten[
ConstantArray[#, 16] & /@
Floor@{0, 2^30 Sqrt[2], 2^30 Sqrt[3], 2^30 Sqrt[5], 2^30 Sqrt[7]}];
kp = Flatten[
ConstantArray[#, 16] & /@
Floor@{2^30 Surd[2, 3], 2^30 Surd[3, 3], 2^30 Surd[5, 3], 2^30 Surd[7, 3],
0}];
I prefer putting j ranges on the LHS of the function rather than with an If on the RHS. Other than that, things seemed quite similar. I also defined my Rotate function in a slightly different way then you:
Rol[x_Integer, n_Integer] :=
Mod[BitOr[BitShiftLeft[x, n], BitShiftRight[x, 32 - n]], 2^32]