What is the method that you can use to convert between bases in Java? It is something like IntegerToBase (int, base), but I cannot remember.
Literally speaking, integer values are not converted from one base to another. Thanks to von Neumann, one of the pioneers of computing, who thought the idea of trying to use base 10 arithmetic on binary circuitry made little sense, integers are stored in binary format and we are not trying to change that :-) What we are talking about is converting them to strings representing them in some base (other that base 10 which is the default) and converting strings to integers in bases other than (the default) base 10. The necessary tools are static methods of the Integer class.
Java provides the Integer.toString(int i, int radix) conversion function which takes an integer and a radix (the base) and returns that integer's string representation in that base.
String hexRepr = Integer.toString(255, 16) // returns "FF"
To go the other way around, i.e. from a string representing a number in a different base there is Integer.parseInt(String s, int radix)
int myNum = Integer.parseInt("FF", 16) // returns 255
To convert a number represented as a base radix1 string to a base radix2 string representation the two methods just mentioned have to be combined as the following examples shows:
int radix1 = 16; // The input will be parsed assuming base 16 representation
int radix2 = 4; // The result will be output using a base 4 representation
String input = "FF"; // which in base 16 represents the number 255
String converted = Integer.toString(Integer.parseInt(radix1Representation, radix1),radix2); /// returns "3333" which in base 4 is the number 255
More details can be found in the API documentation. I have included some of it here, to ensure readers also see the things they need to be careful with when using these methods.
public static String toString(int i, int radix)
This method returns a string representation of the first argument in the radix specified by the second argument.
If the radix is smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX, then the radix 10 is used instead.
If the first argument is negative, the first element of the result is the ASCII minus character '-' ('\u002D'). If the first argument is not negative, no sign character appears in the result.
The remaining characters of the result represent the magnitude of the first argument. If the magnitude is zero, it is represented by a single zero character '0' ('\u0030'); otherwise, the first character of the representation of the magnitude will not be the zero character. The following ASCII characters are used as digits:
0123456789abcdefghijklmnopqrstuvwxyz
These are '\u0030' through '\u0039' and '\u0061' through '\u007A'. If radix is N, then the first N of these characters are used as radix-N digits in the order shown. Thus, the digits for hexadecimal (radix 16) are 0123456789abcdef. If uppercase letters are desired, the String.toUpperCase() method may be called on the result:
Integer.toString(n, 16).toUpperCase()
Source: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toString%28int,%20int%29
public static int parseInt(String s, int radix) throws NumberFormatException
This method parses the string argument as a signed integer in the radix specified by the second argument. The characters in the string must all be digits of the specified radix (as determined by whether Character.digit(char, int) returns a nonnegative value), except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value or an ASCII plus sign '+' ('\u002B') to indicate a positive value. The resulting integer value is returned.
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') or plus sign '+' ('\u002B') provided that the string is longer than length 1.
The value represented by the string is not a value of type int.
Examples:
parseInt("0", 10) // returns 0
parseInt("473", 10) // returns 473
parseInt("+42", 10) // returns 42
parseInt("-0", 10) // returns 0
parseInt("-FF", 16) // returns -255
parseInt("1100110", 2) // returns 102
parseInt("2147483647", 10) // returns 2147483647
parseInt("-2147483648", 10) // returns -2147483648
parseInt("2147483648", 10) // throws NumberFormatException
parseInt("99", 8) // throws NumberFormatException
parseInt("Kona", 10) // throws NumberFormatException
parseInt("Kona", 27) // returns 411787
Source: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt%28java.lang.String,%20int%29
The Integer class offers two utility methods which offer this functionality, although strings are the medium of conversion:
Integer.parseInt(String s, int radix) to parse from a given base
Integer.toString(int i, int radix) to convert to a given base
Note that Integer internally stores values in decimal form (base 10).
For example, to convert 01000 (octal) to 512 (decimal) and back, you can do the following:
String octal = "01000";
int i = Integer.parseInt(octal, 8);
String decimal = Integer.toString(i, 10);
System.out.println(decimal); // prints 512
You can use Integer.parseInt("101", 2) for example, it will give you 5 (correspond decimal number).
Returns an Integer object holding the value extracted from the
specified String when parsed with the radix given by the second
argument. The first argument is interpreted as representing a signed
integer in the radix specified by the second argument, exactly as if
the arguments were given to the parseInt(java.lang.String, int)
method. The result is an Integer object that represents the integer
value specified by the string. In other words, this method returns an
Integer object equal to the value of: (source)
new Integer(Integer.parseInt(s, radix))
From the same source, you also have:
public static String toString(int i,int radix)
Returns a string representation of the first argument in the radix specified by the second argument.
So if you want to convert from binary to decimal:
Integer.parseInt(binary_number_in_string, 2);
if you want from decimal to binary:
System.out.println(Integer.toString(2,2));
To convert from another base to decimal and vise versa you just have to change the radix parameter.
Note that the class Integer have already some default conversation methods, such as:
public static String toBinaryString(int i)
Returns a string representation of the integer argument as an unsigned integer in base 2
(source).
public static String toHexString(int i)
Returns a string representation of the integer argument as an unsigned integer in base 16 (source).
public static String toOctalString(int i)
Returns a string representation of the integer argument as an unsigned
integer in base 8 (source).
As you can see from the return type of the above methods, it is not the integer that are being convert between base. The methods are returning the String representation in a give base of the integer pass as a argument.
Related
I am generating modulus and exponent from Java and .NET system but there are differences in both. I need the out come like .NET in java. Java is adding two extra zeros on hex conversion of modulus and in exponent removing 1 zero but .NET is generating correct. Please see below results from .Net and Java.
If I use toString(16) then its generate below results. toString(16) is not adding two zeros in modulus but removing a zero from exponent where .NET add a 0 in exponent and remove two zeros from modulus which is I want.
String modlusHexString = publicKey.getModulus().toString(16).toUpperCase();
String exponentHexString = publicKey.getPublicExponent().toString(16).toUpperCase();
ModlusHex toString(16): D9B4E023A7CEF604499E184CBA7B7847FE35A824D15FF902EADB952FB54620158A564EFDDB0A66A7647CBDB339359BF6756F5851A73CC1D24859A064DD7AE30B2330F965C54682B10E886D35FE005F42B056C7ABF64D3F6D592AEDC0234417507A0A1432E51C7867E3ACC4867A1AE03EF9E62050180882B18771D5703C8BADCB3AC767CD1A1C0F9344F10B8C82EF5D0ACA4422512EA3ECCB5B71097BDEDAD9BBBE11697D1E61814CF3BBDEB48BDC2C95AA10DFC3F7F794E307D49B5455F928A9BB3ED2F28D6E2974238EFB2D9A822EC1832177CB988206204DF1D9DB7D291E2816576BEBD669184894B526F0B5D10C7D19FA67E79DADDF97D4A3082D4812A27B
ExponentHex toString(16): 10001
I tried below method also to convert BigInteger of modulus and exponent to Hex but no luck-
static String toHex(byte[] ba) {
StringBuilder hex = new StringBuilder(ba.length * 2);
for (byte b : ba) {
hex.append(String.format("%02x", b, 0xff));
}
return hex.toString().toUpperCase();
}
Modlus Hex: 00D9B4E023A7CEF604499E184CBA7B7847FE35A824D15FF902EADB952FB54620158A564EFDDB0A66A7647CBDB339359BF6756F5851A73CC1D24859A064DD7AE30B2330F965C54682B10E886D35FE005F42B056C7ABF64D3F6D592AEDC0234417507A0A1432E51C7867E3ACC4867A1AE03EF9E62050180882B18771D5703C8BADCB3AC767CD1A1C0F9344F10B8C82EF5D0ACA4422512EA3ECCB5B71097BDEDAD9BBBE11697D1E61814CF3BBDEB48BDC2C95AA10DFC3F7F794E307D49B5455F928A9BB3ED2F28D6E2974238EFB2D9A822EC1832177CB988206204DF1D9DB7D291E2816576BEBD669184894B526F0B5D10C7D19FA67E79DADDF97D4A3082D4812A27B
Exponent : 010001
Following is .NET generated HEX of public key modulus and exponent which is correct
.NET
Modulus HEX:
F86020AFD75A03911BE8818BCB506B5DAC2760C68BB46F2A53E10E3E0972A7FFFFF71EAC0E0D73E8FDB4C332C759E781E54C0F1F4637656E6E995873B9580027F49606811C7B5DB458C1BAC3E3D6EB7B77BFE1E55A822F23797E4CB27C7BD88C1B782AEF5235DAE55B937ABB0FFD30AF64F8D69DA07946441D9E4704FA98BD026E00A92851FABC8AB347AB75615ACC8A7CCFDE56B0797DDB70FCA1F28F23F86548AABE6DD89B5CC859BC6352D077F765AAFCF15695215850A8D7E1F9DF187AE0EF1934E096B739E884757F810B3320EFA72BBE2A957CE465E2010A5FD9C96A5F6456658D3BA0DF51B472AFEBEF31C3609B58C6A03C671DA33650039822465179
Exponent : 010001
The problem you are facing results from the behavior of the methods BigInteger.toString(int radix) and BigInteger.toByteArray().
When you call the BigInteger.toString(int radix) method, it returns only the significant digits of the number. So if the value is supposed to be, for example, 05ABFF, it returns only 5ABFF. This is natural when the radix is 10 (we don't expect the big integer 13 to have be converted to something like 013), but this is somewhat counter-intuitive when the radix is 16, as you expect the output to have an even length, exactly two characters for each byte. But that's not how it works.
But when you call your own toHex() method, it is based on the value returned from BigInteger.toByteArray(). Here you have your other problem. This method always returns the number of bytes necessary to represent the number, including a sign bit. Now consider the number 0xD9B4E023. This is actually a negative number if it is considered an integer, but if it is considered as positive by BigInt, you need an extra byte that represents the sign. Hence the additional byte that translates to 00 in your method.
I can think of two possible solutions:
static String toHex(byte[] ba) {
StringBuilder hex = new StringBuilder(ba.length * 2);
boolean skipZeroBytes = true;
for (byte b : ba) {
// As soon as we hit the first non-zero byte, we stop skipping bytes
if (b != 0) {
skipZeroBytes = false;
}
// If the current byte is zero, and we are in skipping mode, skip
if (skipZeroBytes) {
continue;
}
hex.append(String.format("%02X", b, 0xff));
}
if (skipZeroBytes) {
// If we are still in skipping mode, it means all the bytes in the
// array were zero and we skipped them all. So just return the
// representation of a zero.
return "00";
} else {
return hex.toString();
}
}
What we do here is skip all the initial zero bytes until we hit the first non-zero byte, and only then we start interpreting it. Small note: using the format %02X with a capital X gives you uppercase hexadecimal digits and saves the need to call toUpperCase() later.
The other, simpler method is to add the missing zero to the result of BigInteger.toString(int radix):
static String toHex2(BigInteger bi) {
String hex = bi.toString(16).toUpperCase();
if (hex.length() % 2 == 1) {
return "0" + hex;
} else {
return hex;
}
}
i want to convert hexadecimal value to a signed decimal number.like FFFFFB2E to -1234.Is there any method to do this in java?
Use Long.parseLong by passing 16 as radix of the number that you are entering as below:
long myHexNumber = Long.parseLong("FFFFFB2E", 16);
int number = (int)myHexNumber;
System.out.println(number);
Use Integer.parseInt(String, int), per Java documentation:
Parses the string argument as a signed integer in the radix specified by the second argument. The characters in the string must all be digits of the specified radix (as determined by whether Character.digit(char, int) returns a nonnegative value), except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value or an ASCII plus sign '+' ('\u002B') to indicate a positive value. The resulting integer value is returned.
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') or plus sign '+' ('\u002B') provided that the string is longer than length 1.
The value represented by the string is not a value of type int.
Examples:
parseInt("0", 10) returns 0
parseInt("473", 10) returns 473
parseInt("+42", 10) returns 42
parseInt("-0", 10) returns 0
parseInt("-FF", 16) returns -255
parseInt("1100110", 2) returns 102
parseInt("2147483647", 10) returns 2147483647
parseInt("-2147483648", 10) returns -2147483648
parseInt("2147483648", 10) throws a NumberFormatException
parseInt("99", 8) throws a NumberFormatException
parseInt("Kona", 10) throws a NumberFormatException
parseInt("Kona", 27) returns 411787
I have this code:
private String padWithZeroRightToPeriod(String serverFormat, float unformattedNumber, int index) {
int nDigits = getNumberOfDigitsAfterPeriod(serverFormat);
String floatingFormat = "%4." + nDigits + "f";
String formattedPrice = String.format(floatingFormat, unformattedNumber);
When called with unformattedNumber being 846, why is the result " 846" (a space and then the three digits)?
What does the %4. mean?
The docs for String.format refer you to this documentation on format strings, which says:
The format specifiers for general, character, and numeric types have the following syntax:
%[argument_index$][flags][width][.precision]conversion
The optional argument_index is a decimal integer indicating the position of the argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc.
The optional flags is a set of characters that modify the output format. The set of valid flags depends on the conversion.
The optional width is a positive decimal integer indicating the minimum number of characters to be written to the output.
The optional precision is a non-negative decimal integer usually used to restrict the number of characters. The specific behavior depends on the conversion.
The required conversion is a character indicating how the argument should be formatted. The set of valid conversions for a given argument depends on the argument's data type.
From your example output, it appears that getNumberOfDigitsAfterPeriod is returing 0, so your format string is %4.0f. So:
It doesn't have an argument index (there's no $ after the 4)
It has a width (4)
It has a precision (0)
And of course it has a conversion (f)
So 846 is output as " 846" because the width is 4. The width in question is the total number of characters output. Here's a different example: Live Copy
public class Example {
public static void main(String args[]) {
System.out.println(String.format("%8.2f", 846.0));
System.out.println(String.format("%8.2f", 42.4));
}
}
Output:
846.00
42.40
Note that each of those is eight characters long.
public static byte[][] keyArray = new byte[4][4];
String hex = "93";
String hexInBinary = Integer.toBinaryString(Integer.parseInt(hex, 16));
keyArray[row][col] = Byte.parseByte(hexInBinary,2); //this line causes the error
This is the error message I get,
"Exception in thread "main" java.lang.NumberFormatException: Value out of range. Value:"10010011" Radix:2."
I don't want to use getBytes(), because I actually have a long string, "0A935D11496532BC1004865ABDCA42950." I want to read 2 hex at a time and convert to byte.
EDIT:
how I fixed it:
String hexInBinary = String.format("%8s", Integer.toBinaryString(Integer.parseInt(hex, 16))).replace(' ', '0');
keyArray[row][col] = (byte)Integer.parseInt(hexInBinary, 2);
As it is written in the exception message the string you are trying to convert to byte exceeds the max. value of a byte can have.
In your example the string "10010011" equals to 147, but the max value for a byte variable is 2^7 - 1 = 127.
You might want to check the Byte Class documentation;
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Byte.html#MAX_VALUE
So i suggest to use Integer.parseInt(), instead of parseByte method and then cast the int value to byte, integer value 147 will become -109 when you cast it to byte value.
public class ByteConvert {
public static void main(String[] argv) {
String hex = "93";
String hexInBinary = Integer.toBinaryString(Integer.parseInt(hex, 16));
int intResult = Integer.parseInt(hexInBinary,2);
System.out.println("intResult = " + intResult);
byte byteResult = (byte) (Integer.parseInt(hexInBinary,2));
System.out.println("byteResult = " + byteResult);
byte result = Byte.parseByte(hexInBinary,2);
System.out.println("result = " + result);
}
}
C:\JavaTools>java ByteConvert
intResult = 147
byteResult = -109
Exception in thread "main" java.lang.NumberFormatException: Value out of range.
Value:"10010011" Radix:2
at java.lang.Byte.parseByte(Unknown Source)
at ByteConvert.main(ByteConvert.java:9)
As can be seen, parseByte detects a value "larger" than a byte.
According to the java documention at http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Byte.html#parseByte(java.lang.String),
"The characters in the string must all be digits, of the specified radix
(as determined by whether Character.digit(char, int) returns a nonnegative
value) except that the first character may be an ASCII minus
sign '-' ('\u002D') to indicate a negative value."
So the binary representation is not twos-compliment. The byte 10010011 in twos-compliment notation would be negative given that the upper bit is a 1. So if you want to get the same value as the twos-compliment byte 10010011, you would need to do Byte.parseByte("-1101100");.
Put another way, the maximum value an unsigned byte can have is 255. The maximum value a signed byte can have is 127 (because if the most-significant-bit is 1, then it is interpreted as a negative number). However, the issue with parseByte() is that it instead uses an explicit "-" symbol instead of a 1 to indicate negative numbers. This means that the rest of the "byte" can only use 7 bits.
I want to parse an String containing 8 hex-digits (4bytes) but i got an NumberFormatException. What is wrong here?
assertThat(Integer.parseInt("FFFF4C6A",16),is(0xFFFF4C6A));
Your number represents a number greater than that assignable to an int. Try:
Long.parseLong("FFFF4C6A", 16);
which gives 4294921322.
From the doc:
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, …
The value represented by the string is not a value of type int.
and it's the 4th case that you're hitting.
You've exceeded the range of an integer.
Integer.MAX_VALUE = 2147483647
0xFFFF4C6A = 4294921322
Parsing it as a Long works:
Long.parseLong("FFFF4C6A",16)
That is because the Integer.parseInt("FFFF4C6A",16) provided exceeds Integer.MAX_VALUE which is defined as public static final int MAX_VALUE = 0x7fffffff;
Now, as per the Javadoc for parseInt(...), you would hit a NumberFormatException in either of the following cases:
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') or
plus sign '+' ('\u002B') provided that the string is longer than
length 1.
The value represented by the string is not a value of type int.
In your case, since the String value supplied exceeds Integer.MAX_VALUE, you're satisfying the 4th clause for NumberFormatException
Possible Solution: In order to parse this, use Long.parseLong(...) where the MAX_VALUE is defined as `public static final long MAX_VALUE = 0x7fffffffffffffffL
If you just want to represent that hex string as an integer (since it is 32 bits), you need to use BigInteger:
new BigInteger("FFFF4C6A", 16).intValue()
I don't know the assertThat() method, but your hexadecimal number "FFFF4C6A" is to big for an integer.
For example, if you write :
int number = Integer.parseInt("FFFF4C6A",16)
you'll get the same error.
A correct way to write the code would be :
double number = Integer.parseInt("FFFF4C6A",16)