Get same unique id for same string - java

Is there a way to find the same integer/long or any digit number equivalent to a given string using java.
e.g If i give a string "Java_programming" it should give me always something like "7287272" digit.
The generated digit/number should be unique i.e. it should always generate "123" for "xyz" not "123" for "abc".

Call the hashCode method of your String object.
I.e :
String t = "Java_programming";
String t2 = "Java_programming";
System.out.println(t.hashCode());
System.out.println(t2.hashCode());
Gives :
748582308
748582308
Using hashCode in this case will meet your requirements (as you formuled it) but be careful, two different String can produce the SAME hashCode value ! (see #Dirk example)

What are your requirements? You could just use a new BigInteger("somestring".toBytes("UTF-8")).toString() to convert the string to a number, but will it do what you want?

Why don't you create a SHA-1 out of the string and use that as a key?
static HashFunction hashFunction = Hashing.sha1();
public static byte[] getHash(final String string) {
HashCode hashCode = hashFunction.newHasher().putBytes(string.getBytes).hash();
return hashCode.asBytes();
}
You can then do Bytes.toInt(hash) or Bytes.toLong(hash)

Yes, it is possible. You can use String.hashCode() method on string.
Here you find more details how integer returned by this method is created

It depends if you want that 2 different String have to give always 2 different identifiers.
String.hashCode() can do what you want, the same string will give always the same ID but 2 different strings can also give the same ID.
If you want a unique identifier you can i.e. concatenate each byte character value from your string.

First take your string and convert it to a sequence of bytes:
String a = "hello";
byte[] b = a.getBytes();
Now convert the bytes to a numeric representation, using BigInteger
BigInteger c = new BigInteger(b);
Finally, convert the BigInteger back to a string using its toString() method
String d = c.toString();
You are guaranteed to get the same output for the same input, and different outputs for different inputs. You can combine all of these into one step by doing
String d = new BigInteger(a.getBytes()).toString();

Related

Is there any method like char At in Dart?

String name = "Jack";
char letter = name.charAt(0);
System.out.println(letter);
You know this is a java method charAt that it gives you a character of a String just by telling the index of the String. I'm asking for a method like this in Dart, does Dart have a method like that?
You can use String.operator[].
String name = "Jack";
String letter = name[0];
print(letter);
Note that this operates on UTF-16 code units, not on Unicode code points nor on grapheme clusters. Also note that Dart does not have a char type, so you'll end up with another String.
If you need to operate on arbitrary Unicode strings, then you should use package:characters and do:
String name = "Jack";
Characters letter = name.characters.characterAt(0);
print(letter);
Dart has two operations that match the Java behavior, because Java prints integers of the type char specially.
Dart has String.codeUnitAt, which does the same as Java's charAt: Returns an integer representing the UTF-16 code unit at that position in the string.
If you print that in Dart, or add it to a StringBuffer, it's just an integer, so print("Jack".codeUnitAt(0)) prints 74.
The other operations is String.operator[], which returns a single-code-unit String. So print("Jack"[0]) prints J.
Both should be used very judiciously, since many Unicode characters are not just a single code unit. You can use String.runes to get code points or String.characters from package characters to get grapheme clusters (which is usually what you should be using, unless you happen to know text is ASCII only.)
You can use
String.substring(int startIndex, [ int endIndex ])
Example --
void main(){
String s = "hello";
print(s.substring(1, 2));
}
Output
e
Note that , endIndex is one greater than startIndex, and the char which is returned is present at startIndex.

Java - checking encoding of string for unit test?

I have a unit test I was trying to write for a generateKey(int **length**) method. The method:
1. Creates a byte array with size of input parameter length
2. Uses SecureRandom().nextBytes(randomKey) method to populate the byte array with random values
3. Encodes the byte array filled with random values to a UTF-8 String object
4. Re-writes the original byte array (called randomKey) to 0's for security
5. Returns the UTF-8 encoded String
I already have a unit test checking for the user inputting a negative value (i.e. -1) such that the byte array would throw a Negative array size exception.
Would a good positive test case be to check that a UTF-8 encoded String is successfully created? Is there a method I can call on the generated String to check that it equals "UTF-8" encoding?
I can't check that the String equals the same String, since the byte array is filled with random values each time it is called....
source code is here:
public static String generateKey(int length) {
byte[] randomKey = new byte[length];
new SecureRandom().nextBytes(randomKey);
String key = new String(randomKey, Charset.forName("UTF-8"));//Base64.getEncoder().encodeToString(randomKey);
Arrays.fill(randomKey,(byte) 0);
return key;
}
You can convert a UTF8 string to a byte array as below
String str = "私の"; // replace this with your generateKey result
byte [] b = str.getBytes();
String newString;
try {
newString = new String (b, "UTF-8");
System.out.println(newString);
System.out.println("size is equal ? " + (str.length() == newString.length()));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
First, the code you posted is simply wrong: you can't take a random array of bytes and treat it as a UTF-8 string, because UTF-8 expects certain bit patterns to indicate multi-byte characters.
Unfortunately, this failure happens silently, because you're using a string constructor that "always replaces malformed-input and unmappable-character sequences with this charset's default replacement string". So you'll get something, but you wouldn't be able to translate it back to the same binary value.
The comment in the code, however, gives you the answer: you need to use Base64 to encode the binary value.
However, that still won't let you verify that the encoded string is equivalent to the original byte array, because the function takes great care to zero out the array immediately after use (which doesn't really do what the author thinks it does, but I'm not going to get into that argument).
If you really want to test a method like this, you need to be able to mock out core parts of it. You could, for example, separate out the generation of random bytes from encoding, and then pass in a byte generator that keeps track of the bytes that it generated.
But the real question is why? What are you (or more correctly, the person writing this code) actually trying to accomplish? And why won't a UUID accomplish it?

Get the previous and next values of a string

I am using a NoSQL database which doesn't allow equality conditions of attributes that are projected. Eg Unequality operations such as select a from table where a > 10 and is allowed select a from table where b < 10, but select a from table where a = 10 is not allowed. Of course I need to use an equality in my case, so I want to turn a equality operations into an inequality operation.
So I need to retrieve a record by email. If could I would go select email from table where email = 'myemail#email.com', but this is not allowed so I want to get the lexicographic value right before myemail#email.com and the value right after. So the query would look like this:
select email from table where email < [1 value above] and email > [1 value below]
This way the statement would still return myemail#email.com. I am having trouble though how to accomplish this.
Usually to compare strings I go "myemail#email.com".compare("myemail#email.ca") to see which one bigger and which one is smaller. This method compares the values somehow based on lexicographic, but how? My question is how to get the lexicographic value right below a string and the lexicographic value right after the string?
The string immediately after a string is easy. It's just
str + '\0'
This works because '\0' is the lowest possible char value.
The string immediately before str is more tricky. If the string ends in '\0' you can just remove it. If the string doesn't end in '\0' you have serious issues. As an example, let's consider the string "foo".
Each of the following strings is below "foo" and each one is bigger than the last.
"fon" + Character.MAX_VALUE;
"fon" + Character.MAX_VALUE + Character.MAX_VALUE;
"fon" + Character.MAX_VALUE + Character.MAX_VALUE + Character.MAX_VALUE;
...
The largest String value less than "foo" is "fon" followed by something like 2^31 - 4 copies of Character.MAX_VALUE (this may not be right. I'm not sure what the largest possible length of a char[] is). However, you will not be able to store such a string in memory.
You should therefore try to find an different solution to your problem.
Assuming your alphabet is a-z0-9, and case-insensitive, you can treat your string as a base-36 number and simply increment/decrement the values using simple arithmetic.
Java's Long.valueOf method allows you to take a String with a given radix, and convert it to it's (base 10) Long equivalent. Once you have a Long instance, you can simply add 1 to get the next value.
public static String nextString(String str) {
return Long.toString(Long.valueOf(norm(str), 36) + 1, 36);
}
To reverse the operation, you can use the Long.toString method, which takes a long instance and converts it to a String representation, with a specified radix. So you can represent your base-10 long as a base-36 number, which will include the letters a-z.
public static String prevString(String str) {
return Long.toString(Long.valueOf(norm(str), 36) - 1, 36);
}
You'll want to normalize your strings when using these methods, so this will filter our invalid characters, ensure that everything is lower-case, and prevent null pointer exceptions or number format exceptions.
private static String norm(String str) {
if (str == null) {
return "0";
}
return str.toLowerCase().replaceAll("[^a-z0-9]", "");
}

Converting an integer and a character to a string in java

I'm trying to create a string comprised of a single letter, followed by 4 digits e.g. b6789. I'm getting stuck when I try to convert a character, and integer to one String. I can't use toString() because I've overwritten it, and I assume that concatenation is not the best way to approach it? This was my solution, until I realised that valueof() only takes a single parameter. Any suggestions? FYI - I'm using Random, because I will be creating multiples at some point. The rest of my code seemed irrelevant, and hence has been omitted.
Random r = new Random();
Integer numbers = r.nextInt(9000) + 1000;
Character letter = (char)(r.nextInt(26) + 'a');
String strRep = String.valueOf(letter, numbers);
I think they mean for you not to use concatenation with + operator.
Rather than that, there's a class called StringBuilder which will do the trick for you. Just create an empty one, append anything you need on it (takes Objects or primitives as arguments and does all the work for you), and at the end, just call at its "toString()" method, and you'll have your concatenated String.
For example
StringBuilder sb = new StringBuilder();
sb.append("Foo");
sb.append(123);
return sb.toString();
would return the string Foo123
you can use:
Character.toString(char)
which is
String.valueOf(char)
in reality which also works.
or just use
String str = "" + 'a';
as already mentioned but not very efficient as it is
String str = new StringBuilder().append("").append('a').toString();
in reality.
same goes for integer + string or char + int to string. I think your simpliest way would be to use string concatenation
Looks like you want
String.valueOf(letter).concat(numbers.toString());

(JAVA) how to use charAt() to find last digit number (or rightmost) of any real number?

Hello Im new to programming
and as title I was wonder how you can find last digit of any given number?
for example when entering in 5.51123123 it will display 3
All I know is I should use charAt
Should I use while loop?
thanks in advance
You would want to do something like this:
double number = 5.51123123;
String numString = number + "";
System.out.println(numString.charAt(numString.length()-1));
When you do the number + "", Java "coerces" the type of number from a double to a string and allows you to perform string functions on it.
The numString.length()-1 is because numString.length() returns the count of all the characters in the string BUT charAt() indexes into the string and its indexing begins at 0, so you need to do the -1 or you'll get a StringIndexOutOfBoundsException.
You can use below function simply and you can customize data types accordingly,
private int getLastDigit(double val){
String tmp = String.valueOf(val);
return Integer.parseInt(tmp.substring(tmp.length()-1));
}
You can't use charAt on a floating point variable (or any other data type other than Strings). (Unless you define a charAt method for your own classes...)
You can, however, convert that floating point number to a string and check the charAt(str.length()-1).
Convert your float variable to string and use charAt(strVar.length - 1).
double a=5.51123123;
String strVar=String.valueOf(a);
System.out.print(strVar.charAt(strVar.length -1);
Double doubleNo = 5.51123123;
String stringNo = doubleNo.toString();
System.out.println(stringNo.charAt(stringNo.length()-1));

Categories

Resources