java.lang.NumberFormatException: Converting string to ASCII - java

I am trying to convert my string to ASCII value through my hash function, which looks like this:
public long hash(String word){
StringBuilder sb = new StringBuilder();
String ascString = null;
long asciiInt;
for(int i=0;i<word.length();i++){
sb.append((int)word.charAt(i));
}
ascString = sb.toString();
asciiInt = Long.parseLong(ascString);
return asciiInt;
}
and later on, I will call it in my insert() method to perform quadratic hashing using a hashTable, and the insert method looks like this:
public void insert(Word word){
int start = (int)(hash(word.text)%tableSize);
int key = start;
int attempt=0;
while(hashTable[key]!=null){
attempt++;
key=(start+(int)Math.pow(attempt,2))%tableSize;
}
hashTable[key]=word;
}
However, it throws the java.lang.NumberFormatException if the string I am trying to convert has more than 6 characters. Can anyone help me fix it or a better ways of coming up with the key value for my hash table?
Thanks!

The value you're attempting to gain (base 10 long) can't be achieved from your string because you've the wrong base. Say the string is "DEADBEEF". Because all digits of DEADBEEF are base 16, you can specify the radix as 16 and use
Long.parseLong(DEADBEEF, 16);
The non-radix method assumes that the string contains a base-10 long when really the number is much longer (DEADBEEF is 3735928559 in base 10). Check your string maybe?

Related

Encrypt using reapeting XOR

i have to encrypy a string using repeating XOR with the KEY:"ICE".
I think that i made a correct algorith to do it but the solution of the problem has 5 byte less then my calculated Hex string, why? Until this 5 bytes more the string are equals.
Did i miss something how to do repeating XOR?
public class ES5 {
public static void main(String[] args) throws UnsupportedEncodingException {
String str1 = "Burning 'em, if you ain't quick and nimble";
String str2 = "I go crazy when I hear a cymbal";
String correct1 = "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a2622632427276527";
byte[] cr = Encript(str1.getBytes(StandardCharsets.UTF_8),"ICE");
String cr22 = HexFormat.of().formatHex(cr);
System.out.println(cr22);
System.out.println(correct1);
}
private static byte doXOR(byte b, byte b1) {
return (byte) (b^b1);
}
private static byte[] Encript(byte[] bt1, String ice) {
int x = 0;
byte[] rt = new byte[bt1.length];
for (int i=0;i< bt1.length;i++){
rt[i] = doXOR(bt1[i],(byte) (ice.charAt(x) & 0x00FF));
x++;
if(x==3)x=0;
}
return rt;
}
}
Hmmm. The String contains characters, and XOR works on bytes.
That's why the first thing is to run String.getBytes() to receive a byte array.
Here, depending on the characters and their encoding the amount of bytes can be more than the amount of characters. You may want to print and compare the numbers already.
Then you perform XOR on the bytes, which may bring you into a completely different area for characters - so you cannot rely on new String(byte[]) at all. Instead you have to create a HEX string representation of the byte[].
Finally compare this HEX string with the value in correct. To me that string already looks like a HEX representation, so do not apply HEX again.

java - Enforce 4 digit hex representation of a binary number

Below is a snippet of my java code.
//converts a binary string to hexadecimal
public static String binaryToHex (String binaryNumber)
{
BigInteger temp = new BigInteger(binaryNumber, 2);
return temp.toString(16).toUpperCase();
}
If I input "0000 1001 0101 0111" (without the spaces) as my String binaryNumber, the return value is 957. But ideally what I want is 0957 instead of just 957. How do I make sure to pad with zeroes if hex number is not 4 digits?
Thanks.
You do one of the following:
Manually pad with zeroes
Use String.format()
Manually pad with zeroes
Since you want extra leading zeroes when shorter than 4 digits, use this:
BigInteger temp = new BigInteger(binaryNumber, 2);
String hex = temp.toString(16).toUpperCase();
if (hex.length() < 4)
hex = "000".substring(hex.length() - 1) + hex;
return hex;
Use String.format()
BigInteger temp = new BigInteger(binaryNumber, 2);
return String.format("%04X", temp);
Note, if you're only expecting the value to be 4 hex digits long, then a regular int can hold the value. No need to use BigInteger.
In Java 8, do it by parsing the binary input as an unsigned number:
int temp = Integer.parseUnsignedInt(binaryNumber, 2);
return String.format("%04X", temp);
The BigInteger becomes an internal machine representation of whatever value you passed in as a String in binary format. Therefore, the machine does not know how many leading zeros you would like in the output format. Unfortunately, the method toString in BigInteger does not allow any kind of formatting, so you would have to do it manually if you attempt to use the code you showed.
I customized your code a bit to include leading zeros based on input string:
public static void main(String[] args) {
System.out.println(binaryToHex("0000100101010111"));
}
public static String binaryToHex(String binaryNumber) {
BigInteger temp = new BigInteger(binaryNumber, 2);
String hexStr = temp.toString(16).toUpperCase();
int b16inLen = binaryNumber.length()/4;
int b16outLen = hexStr.length();
int b16padding = b16inLen - b16outLen;
for (int i=0; i<b16padding; i++) {
hexStr=('0'+hexStr);
}
return hexStr;
}
Notice that the above solution counts up the base16 digits in the input and calculates the difference with the base16 digits in the output. So, it requires the user to input a full '0000' to be counted up. That is '000 1111' will be displayed as 'F' while '0000 1111' as '0F'.

Save a hex String to File.hex in java

I have a String which contains hex values. Now i want to write this exact string to a file with the ending .hex . How can i realize this in java?
I already tried to convert the Hex Values into ASCII and then write this string into a file.
But all Hex Values which are higher then 127(dec) can't be processed correctly.
86(hex) is transformed to ?(char), which is 3F(hex) and not 86(hex).
You can try to take each char of your string, convert it to integer and then write values in bytes in a file. To do the opposite process, you just have to read the file into a byte array and convert each byte into a char to retrieve your string. Then I'm sure you can find some algorithm to cast your string into Hex string.
For me the Answer was this:
Under Projectproperties i needed to set the Text-file-Encoding to ISO-8859-1.
Then my old procedure worked very well.
public static String hexToASCII(String hex){
if(hex.length()%2 != 0){
System.err.println("requires EVEN number of chars");
return null;
}
StringBuilder sb = new StringBuilder();
for( int i=0; i < hex.length()-1; i+=2 ){
String output = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(output, 16);
sb.append((char)decimal);
}
return sb.toString();
}

NumberFormatException, BigInteger in java

Getting following run-time error
C:\jdk1.6.0_07\bin>java euler/BigConCheck
Exception in thread "main" java.lang.NumberFormatException: For input string: "z
"
at java.lang.NumberFormatException.forInputString(NumberFormatException.
java:48)
at java.lang.Integer.parseInt(Integer.java:447)
at java.math.BigInteger.<init>(BigInteger.java:314)
at java.math.BigInteger.<init>(BigInteger.java:447)
at euler.BigConCheck.conCheck(BigConCheck.java:25)
at euler.BigConCheck.main(BigConCheck.java:71)
My Code
package euler;
import java.math.BigInteger;
class BigConCheck
{
public int[] conCheck(BigInteger big)
{
int i=0,q=0,w=0,e=0,r=0,t=0,mul=1;
int a[]= new int[1000];
int b[]= new int[7];
BigInteger rem[]= new BigInteger[4];
BigInteger num[]= new BigInteger[4];
for(i=0;i<4;i++)
num[i]=big; // intialised num[1 to 4][0] with big
String s="1",g="0";
for(i=0;i<999;i++)
s = s.concat(g);
BigInteger divi[]= new BigInteger[4];
for(i=0;i<5;i++)
{
divi[i]=new BigInteger(s);
int z = (int)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger("z"); // intialised div[1 to 4][0] with big
divi[i]=divi[i].divide(zz);
}
for(i=0;i<996;i++) // 5 consecative numbers.
{
for(int k=0;k<5;k++)
{
rem[k] = num[k].mod(divi[k]);
b[k]=rem[k].intValue();
mul= mul*b[k];
/*int z = (int)Math.pow((double)10,(double)(k+1));
String zz = "z";
BigInteger zzz = new BigInteger(zz);
num[k]=num[k].divide(zzz); */
}
a[i]=mul;
for(int p=0;p<5;p++)
{
BigInteger qq = new BigInteger("10");
num[p]=num[p].divide(qq);
}
}
return a;
}
public int bigestEleA(int u[])
{
int big=0;
for(int i=0;i<u.length;i++)
if(big<u[i])
big=u[i];
return big;
}
public static void main(String args[])
{
int con5[]= new int[1000];
int punCon;
BigInteger bigest = new BigInteger("7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450");
BigConCheck bcc = new BigConCheck();
con5=bcc.conCheck(bigest);
punCon=bcc.bigestEleA(con5);
System.out.println(punCon);
}
}
please point out whats goes wrong # runtime and why
thanks in advance...
This is the line causing you grief:
BigInteger zz = new BigInteger("z"); // intialised div[1 to 4][0] with big
While BigInteger does work with String's, those String's must be parsable into numbers.
EDIT**
Try this:
Integer z = (Integer)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger(z.toString());
new BigInteger("z"); is not meaningful. You can only pass numbers in constructor.
This is pretty obvious, so the next time you get an exception go the the exact line in your code shown in the exception stacktrace and you will most likely spot the problem.
BigInteger Javadoc states for BigInteger(String value)
Translates the decimal String
representation of a BigInteger into a
BigInteger. The String representation
consists of an optional minus sign
followed by a sequence of one or more
decimal digits. The character-to-digit
mapping is provided by
Character.digit. The String may not
contain any extraneous characters
(whitespace, for example).
So your code:
BigInteger zz = new BigInteger("z"); // intialised div[1 to 4][0] with big
is totally incorrect, but this is correct:
BigInteger zz = new BigInteger("5566");
EDIT: Based on your comment, this would be simpler by using the String.valueOf() method:
int z = (int)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger(String.valueOf(z));
BigInteger zz = new BigInteger("z");
you are passing non-numerical string thats the reason.
EDIT:
It takes string but it expects the string to be a numerical value. "z" does not have any numerical meaning.
Could it be that you want this instead?
int z = (int)Math.pow((double)10,(double)i);
BigInteger zz = new BigInteger(z);
Note the missing quotes here. (Of course, this will only work for i < 10.)
A common mistake is writing
new BigInteger("",num)
instead of
new BigInteger(""+num)
For those interested in generating longs with characters without hashing, it is possible to transform characters to long via BigInteger simply by using the constructor with a radix: BigInteger(String value, int radix)
There is a catch thought, the int which defines the log base, must scale not with the length of the String, but instead with the number of characters that make out the collection of characters that will be used in the creation of the String.
As far as I'm aware, for an alpha numeric collection, the int is 36 (26 + 10), this may be wrong thought.
There is also a limitation, I believe there are symbols that simply cannot be parsed, like "-" or " " or "_" (I've tried adding to the int base radix and nothing) which means the String must be transformed before parsing and it cannot be returned back to String after it being parsed via BigInteger.
Why is it useful?? I don't know haha, I have use it to autogenerate id's from Strings ,instead of using hashes, I remember somhwere this is kinda better than hashcode since a hash from String does not ensure uniqueness, an also this method as opposed to base Encoding gives extricity a long value, which may be useful for many api's that require a long id.

Convert a base25 String to binary String in Java

So I have a set of base digits like "BCDFGHJKLMNPQRSTVWXZ34679"
how do I convert a value say "D6CN96W6WT" to binary string in Java?
This should work (assuming 0,1 for you binary digits):
// your arbitrary digits
private static final String DIGITS = "BCDFGHJKLMNPQRSTVWXZ34679";
public String base25ToBinary(String base25Number) {
long value = 0;
char[] base25Digits = base25Number.toCharArray();
for (char digit : base25Digits) {
value = value * 25 + DIGITS.indexOf(digit);
}
return Long.toString(value, 2);
}
Off the top of my head, for base-25 strings.
Integer.toString(Integer.valueof(base25str, 25), 2)
Its a little unclear from your question whether you're talking about actual 0-9-Z bases, or a number encoding with an arbitrary list of symbols. I'm assuming the first, if its the later then you're out of luck on built-ins.

Categories