I have a String variable that I want to convert to a long variable.
The problem is that the String variable will never contain any numbers, so simply calling Long.parseLong(myString); will throw a NumberFormatException.
To clarify my intentions:
I have a method that returns a long from a String in-parameter. I want the method to generate an ID based on the String variable, to later be able to group the long values.
I might solve this using a RegEx expression, but my question is if there's any straight forward way to get a long value of a String?
You say you want a long value. The built in hashCode() returns an int, not a long. If you really do need a long then you need to use a hashing method that returns a long. There are a number of possibilities, though I usually suggest the FNV hash for non-cryptographic purposes. It is very easy to code and comes in a wide range of sizes, 64-bit included.
ETA: Code for the FNV hash is on the FNV website that I linked to. Things to be careful of are 1) unsigned v. signed 64-bit numbers and 2) character encodings.
long FNV64Hash(String inString) throws UnsupportedEncodingException {
// FNV-64 constants.
long FNVprime = 1099511628211L;
// Needs workround for unsigned 64-bit: 14695981039346656037.
long FNVbasis = (146959810393466560L * 100L) + 37L;
// Alternative: long FNVbasis = -3750763034362895579L;
// Convert string to bytes.
byte[] bytes = inString.getBytes("UTF-8"); // Specify a character encoding.
long hash = FNVbasis;
for (byte aByte : bytes) {
hash ^= aByte;
hash *= FNVprime;
}
return hash;
} // end FNV64Hash()
if you want a simple and easy way , you can use hashCode() in java , and here is an example
import java.io.*;
public class StringHashing{
public static void main(String args[]){
String Str = new String("HELLO WORLD !!");
System.out.println("Hashcode for Str :" + Str.hashCode() );
}
}
or you can implement your own hash function
Related
Hiii,I need to do the opposite of what my hash method does, I want a number to convert it to a string, unlike my other method.
I need you to do it in the same way coding as decoding
That would only be possible if there was a 1 to 1 mapping between Strings and longs. Since there are 264 possible long values, and many many more possible String values (even if you limit yourself to Strings of 64 characters, there are still K64 of them, where K is the number of possible unique characters), there cannot be a method that reverses your long hash(String c) method for all possible Strings.
I think that you are trying to implement the Vigenère cipher.
I have fixed your code for executing the two functions (hash and hash2) and I have noticed that hash("javaguay") returns the long number 2485697837967351 and then hash2(2485697837967351L) returns yaugavaj, the reverse string that you want.
A quick response could be the next, but I think you must fix your algorithm.
Add these lines to the end hash2 function:
String res2 = "";
for (int i = res.length() -1; i >=0; i--) {
res2 += res.charAt(i);
}
return res2;
Every object in Parse.com has your own ObjectId, that is a string with 10 char and apparently it is created by this regex: [0-9a-zA-Z]{10}.
Example of ObjectId in Parse:
X12wEq4sFf
Weg243d21s
zwg34GdsWE
I would like to convert this String to Long, because it will save memory and improve searching. (10 chars using UTF-8 has 40 bytes, and 1 long has 8 bytes)
If we calculate the combinations, we can find:
String ObjectId: 62^10 = 839299365868340224 different values;
long: is 2^64 = 18446744073709551616 different values.
So, we can convert these values without losing information. There is a simple way to do it safely? Please, consider any kind of encoding for Chars (UTF-8, UTF-16, etc);
EDIT: I am just thinking in a hard way to solved it. I am asking if there is an easy way.
Your character set is a subset of the commonly-used Base64 encoding, so you could just use that. Java has the Base64 class, no need to roll your own codec for this.
Are you sure this is actually valuable? "because it will save memory and improve searching" seems like an untested assertion; saving a few bytes on the IDs may very well be offset by the added cost of encoding and decoding every time you want to use something.
EDIT: Also, why are you using UTF-8 strings for guaranteed-ascii data? If you represent 10 char IDs as a byte[10], that's just 10 bytes instead of 40 (i.e. much closer to the 8 for a long). And you don't need to do any fancy conversions.
Here's a straightforward solution using 6 bits to store a single character.
public class Converter {
private static final String CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static int convertChar(char c) {
int ret = CHARS.indexOf( c );
if (ret == -1)
throw new IllegalArgumentException( "Invalid character encountered: "+c);
return ret;
}
public static long convert(String s) {
if (s.length() != 10)
throw new IllegalArgumentException( "String length must be 10, was "+s.length() );
long ret = 0;
for (int i = 0; i < s.length(); i++) {
ret = (ret << 6) + convertChar( s.charAt( i ));
}
return ret;
}
}
I'll leave the conversion from long to String for you to implement, it's basically the same in reverse.
P.s.: If you really want to save space, don't use Long, it adds nothing compared to the primitive long except overhead.
P.s 2: Also note that you aren't really saving much with this conversion: storing the ASCII characters can be done in 10 bytes, while a long takes up 4. What you save here is mostly the overhead you'd get if you stored those 10 bytes in a byte array.
I have some Java code that converts a Hexadecimal string into bytes. It seems to work okay for very short hexadecimal strings but flags an error if I use a long string, but I cant figure out why. I'm new to Java and programming in general. Feel free to point out any other areas which I could improve.
Here is my code:
public class Hextobinary {
static String hexToBinary(String hex) {
int i = Integer.parseInt(hex, 16);
String bin = Integer.toBinaryString(i);
return bin;
}
public static void main(String[] args) {
String h = "5F";
String x = hexToBinary(h);
System.out.println(x);
}
}
Many Thanks
There is a built-in for this using DatatypeConverter, so you may not have to do it yourself.
import javax.xml.bind.DatatypeConverter;
public class HexUtils {
public String toHex(final byte[] arr) {
return DatatypeConverter.printHexBinary(arr);
}
public byte[] fromHex(final String str) {
return DatatypeConverter.parseHexBinary(str);
}
}
You are parsing your string to an int. That will work for short hex strings, but not for longer ones. An int is 32 bits, or 8 hex characters. Any string longer than that will not fit into an int.
If you do write your own method, then split the hex string up into two character chunks, and process each pair of characters separately into a byte, and store the bytes in a byte array. That will allow you to deal with longer hex strings.
If you are using huge strings, the type int (Integer) of the variable i cannot store the value contained in the string hex. An Integer can only store values ranging from -80000000 (hexadecimal) to +7FFFFFFF. Any longer string will cause your function to produce false results.
One quick solution is to use the type Long (and the function parseLong) instead of Integer. The type Long can hold values ranging from -8000000000000000 (hexadecimal) to +7FFFFFFFFFFFFFFF. But if you need to convert longer strings, this is not going to work anymore.
I am making an application that involves a seed to generate a world and some games let you provide that seed with text. I'm wondering how would you 'convert' a string to an integer.
A simple way would be to use the ASCII values of all the characters and append them to a string which you would then parse to an integer, but that severely limits the size of the string. How would you be able to do this with a larger string?
EDIT: 64 bit not 32
I would just call String.hashcode(). The standard String.hashcode() function makes use of all characters in the target string and gives good dispersal.
The only thing I would question is whether 32 bits of seed is going to be enough. It might mean that your world generator could generate at most 232 different worlds.
Random seeds for Random can be at least 48-bit, ideally 64-bit. You can write your own hash code like this.
public static long hashFor(String s) {
long h = 0;
for(int i = 0; i < s.length(); i++)
h = h * 10191 + s.charAt(i);
return h;
}
The Standard way for converting a String to Integer is using Integer.parseInt(String);
You pass the string into this and it would convert the String to int. Try it and let me know!
I want to compute Hash of a String, but the Hash value should be a number (long or integer).
In other words I want to compute integer hash of a string.
Collusion resistance in not the concern.
Is there an way to convert MessageDigest of SHA-256 to a number.
I am using Java to accomplish this.
Try to call hashCode() method. It is already implemented and does exactly what you want.
Most obviously there is a hashCode() method on String
As for converting the MessageDigest to a number, you can either use hashCode again or take the byte array from the digest and compact this down to whatever size you want, integer, long or whatever with (say) xor.
public int compactDigest(MessageDigest digest) {
byte [] byteArr = digest.digest();
// +3 since conversion to int array with divide length by four.
// and we don't want to lose any bytes.
ByteBuffer bytes = ByteBuffer.allocate(byteArr.length + 3);
bytes.put(byteArr);
bytes.rewind();
IntBuffer ints = bytes.asIntBuffer();
int compactDigest = 0;
for (int i = 0; i < ints.limit(); ++i) {
compactDigest ^= ints.get(i);
}
return compactDigest;
}
A Sha Hash has 256 Bits e.g.
"364b7e70a9966ef7686ab814958cd0017b7f19147a257d40603d4a1307662b42"
this will exceed the range of long and integer.
You could use new BigInteger( hash, 16 ); for a decimal representation.
public static void main(String[] args) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update("string".getBytes() );
byte[] hash = digest.digest();
BigInteger bi = new BigInteger( hash );
System.out.println( "hex:" + bi.toString(16) + "\r\ndec:" + bi.toString() );
}
class String has a hashcode method, like any other Java class, which transforms the string into a number. See the documentation of this method for the exact algorithm it uses.
every object in java has hashCode() method. You can override it and specify your own logic. Look at the examples.
Please find it here: http://pastebin.com/j6Cffkcp;
I but it returns only string.
Cryptographic hashes created using the JCE classes (MessageDigest in your case) are essentially a sequence of bytes (256 bits for SHA-256). If you wish to store and manage these are numbers, you'll need to convert these into BigInteger or BigDecimal objects (given the length of the digest).
It is not always that a cryptographic hash of String objects are computed, and it is often done for the purpose of one-way encryption of secrets. If you are using the hash for other purposes, especially to ensure some sort of uniqueness among the Strings (that would be important when storing these objects in a hash map), you're better off using the hash value computed by the String.hashCode method.