BIgMAth from base64 encoded string
I'm trying to create a BigInteger from a source that is a base64 encoded string. The BigInteger seems to only support radix up to 36. I have a couple of questions.
1) Why does BigInteger not support higher radix?
2) Anyone have any advice on how to manually make the BigInteger from a base64 string? Obviously I can change the encoding myself to a lower radix, but I thought someone might have a better idea?
Thanks,
Chad
Update. So I'm using the apache commons codec to decode the base64 string into binary bytes. Then I create the BigInteger from the binary byte array. However, I'm finding that the BigInteger is a negative number. BigInteger API says it interprets the byte[] of binary data as being in twos complement. I suspect that the base64 data wasn't in two's complement? Does this make sense? Anyone know how to figure out if this is the problem.
Well, what was the original data (the bytes, I mean)? What format was it in?
Base64 is not a Radix in the sense of Decimal or Hex.
The javadoc for one of the BigInteger constructors -
BigInteger
public BigInteger(int signum,
byte[] magnitude)
Translates the sign-magnitude representation of a BigInteger into a BigInteger. The sign is represented as an integer signum value: -1 for negative, 0 for zero, or 1 for positive. The magnitude is a byte array in big-endian byte-order: the most significant byte is in the zeroth element. A zero-length magnitude array is permissible, and will result inin a BigInteger value of 0, whether signum is -1, 0 or 1.
Parameters:
signum - signum of the number (-1 for negative, 0 for zero, 1 for positive).
magnitude - big-endian binary representation of the magnitude of the number.
Throws:
NumberFormatException - signum is not one of the three legal values (-1, 0, and 1), or signum is 0 and magnitude contains one or more non-zero bytes.
so to force to be positive make the first parameter a 1 .
Message was edited by:
sabre150
> Base64 is not a Radix in the sense of Decimal or
> Hex.
I have a vague sense of why this is. I mean I understand that base64 is more of an encoding than a math thing, but could you elaborate on what differentiates base64 from hex, in the sense that hex is more of a true radix?
> > Base64 is not a Radix in the sense of Decimal or
> > Hex.
>
> I have a vague sense of why this is. I mean I
> understand that base64 is more of an encoding than a
> math thing, but could you elaborate on what
> differentiates base64 from hex, in the sense that hex
> is more of a true radix?
Having thought about this for a bit longer, I now think I was wrong in my assertion and I now consider Base64 as a Radix 64 encoding. Even so, I don't think that BigDecimal should know how to convert Base64 to a BigInteger since it is not a usual encoding for numbers.
I'm baffled by this question too. I can understand encoding an array of bytes in Base64, so you can put it into a place that only accepts simple text, but I can't understand the point of making that into a big integer.
> I'm baffled by this question too. I can understand
> encoding an array of bytes in Base64, so you can put
> it into a place that only accepts simple text, but I
> can't understand the point of making that into a big
> integer.
I suspect that the point is concerned with extracting the public key from an XML file as in the OP's thread - http://forum.java.sun.com/thread.jspa?threadID=5136033&messageID=9495086#9495086 .
Yes. I've been sent a public key, from a .NET house, that comes in an xml file with the modulus and exponent encoded in base64. The encryption api works with BigIntegers.
> Yes. I've been sent a public key, from a .NET house,
> that comes in an xml file with the modulus and
> exponent encoded in base64. The encryption api works
> with BigIntegers.
java.security.interfaces.RSAPublicKey extends
java.security.interfaces.RSAKey. Between them they define two methods
BigInteger getPublicExponent()
and BigInteger getModulus()
It is fairly trivial to create an implementation that takes as input the XML files, extracts the exponent and modulus and exports them though the above methods.
I published an implementation of this a couple of years ago but I can't find it. I do remember that it is important that, when constructing the BigInteger values for the Base64 decoded values, to force the BigIntegers to be positive by using the BigInteger constructor I quoted earlier.
I guess I've now just refined my understanding of the question. At this point, I'm concerned about how I would "know" whether a base64 encoded set of bytes should be interpreted as a twos complement or not, signed or unsigned I guess I'm saying.
In my specific case, I know that the domain rules forbid a negative number so I can assume the encoded bytes are unsigned. BUT . . . I guess its impossible to know whether a number is signed or unsigned ( twos complement or not ) just from the base64 encoding. Does this sound right?
And, then, does this logic apply to hex numbers. If I see a string of hex characters, can I "know" from them whether their underlying bits are would represent a signed or unsigned number?
Yes, that other constructor is what I needed. Thanks!