Get a String value from its hashCode [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
Is there an easy way to get the value of a string using its hashcode? Let me explain:
I have a string variable which has value Hello Guys. It is saved here: String#dye63g. Now, I want to get the string value Hello Guys from String#dye63g.

Based on your comments on this question, your question is REALLY asking:
For an object whose class does not override the default toString() from java.lang.Object itself, can I derive the value again?
The answer is a resounding no. It's NOT A HASH. It's the fully qualified class name, an # symbol, then in hexdigits (so 0-9a-f, not y and g like in your example), the value returned by System.identityHashCode(obj).
This code has no relationship at all with the value of it and isn't the hashCode of that object. It's, usually, its memory address or some modification of that principle.
You can trivially test this:
class Test {
public static void main(String[] args) {
System.out.println(System.identityHashCode("Hey, there!"));
}
}
Run that a few times. The same value might come out (it depends on your system and VM impl), but now run the same code on a different VM, or on a different computer, or reboot and run it again. Different values come out. That should make it rather obvious that you can't.
A second issue is the pigeonhole principle. That hash value is always exactly 32 bits long (why? Well, System.identityHashCode returns an int and those only have 32 bits. Each letter (0-9a-f) represents 4 bytes, hence why that thing after the # is always 8 characters long: each character is 4 bits, 8*4 = 32.
You can test that too. Copy/paste the collected works of Shakespear into a single gigantic string, and now invoke identityHashCode on that - it's still just a short number.
There are 4 billion different numbers that an int can represent and that's it. However, there are more than 4 billion strings imaginable (there are an infinite amount of them, in fact). Hence, there must exist an infinite amount of different strings that all so happen to hash to, say, 1234abcd. Thus, given the hash 1234abcd, it is impossible to say which string produced it - after all, an infinite amount of strings exist that hash to that value. And that's presuming the hashing is 'constant' (same string results in the same hash, e.g. what string's own .hashCode() method does). System.identityHashCode isn't even that and in fact has no relationship at all to the actual value. The number you get depends on, effectively, the memory load of the system when you boot the JVM, more or less.

Related

Saving a String into a file, then loading it into a String variable will give a "different" string that seems to have the exact same name [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 3 years ago.
So I am having an issue, I put my self to the test of creating a 2D sandbox game kind of for fun, but has turned out evolving into something a bit more after about a week, but, to the point, I am saving chunk data into a few files, these are just .file or, just the most basic file type I assume, and the problem persists even using .txt files.
So what's happening is after saving a file containing the object name, x, and y positions, I am creating an object in a linked list using that information, when I enter a new "chunk", but things are not exactly right, somehow, my images load up for the tiles correctly, which is handled in the constructor for that tile, being called after it is added to the list, however, what made me notice is I have a check in the tiles update method, to see if it wants to change to a different grass texture, and it doesn't happen, so I did some checking and printing, and well, I can tell that the name variable certainly contains the desired name, eg. "dirt", however it does not equal "dirt", so I thought it was catching some spaces and I even trimmed the String, and when I run a test like
if(name == "dirt")System.out.print("dirt is actually "+name);
else System.out.print("dirt is apparently not "+name);
and the result is always, "dirt is apparently not dirt", with no spaces, and even when looking in the actual file I save it to, it saves the name fine, I have them saving in an order like so;
name x y
eg.
dirt 0 560
dirt 28 560
and so on, these all load in position perfectly fine and what stumps me is that the initial image loads in correctly, which is quite explicit, a switch statement to determine what the image, material type and such should be..
I was wondering if anyone has come across something like this and what it could possibly be.
Also any code desired I will add to the desc.
(I didn't know so many people would be so quick to help. Thank you all, I know it was a simple problem, but it had me super confused, now thanks to you all I understand something about comparing variables and objects I should have really known before, and which is really important
.)
Chances are the result is "dirt" but you're not testing it correctly.
Test should be if name.equals("dirt") ... not the equality operator ==.
See: How do I compare strings in Java?
Equality in Java:
String dirt1 = "dirt";
String dirt2 = new String("dirt");
System.out.println(dirt1 == "dirt"); // TRUE
System.out.println(dirt1 == dirt2); // FALSE
System.out.println(dirt1 == dirt2.intern()); // TRUE
System.out.println(dirt1.equals(dirt2)); // TRUE

Struggling to understand Random class constructor with one parameter of long type [duplicate]

This question already has answers here:
What is the use of the Random(long) constructor?
(5 answers)
Closed 6 years ago.
I'm relatively new to java and is studying the random class in Java se8. I'm struggling to understand the random class constructor with one parameter of type long. I have attached a screen shot of the explanation in Java documentation, but I'm really struggling to understand what it actually means. Could someone please kindly explain it to me?
A pseudorandom number generator does not actually create random numbers. Instead, it has an internal state and performs a calculation on it that produces a seemingly random number and updates the internal state (so that you get a different number the next time you ask the generator for one).
The sequence of numbers in completely determined by the internal state. In this case, it is a long (for cryptographically strong PRNG it will be something bigger). For the same long seed, you will get the same sequence of numbers back.
You might want to do that in order to reproduce a previous sequence exactly. If you don't care, you can leave the seed unspecified (in this case some default will be supplied that is different every time).

Why the private package String constructor (int, int, char[]) has been removed? [duplicate]

This question already has answers here:
Java 7 String - substring complexity
(5 answers)
Closed 7 years ago.
In Java 6, there was a package private constructor to return a new String with the offset being changed.
643 // Package private constructor which shares value array for speed.
644 String(int offset, int count, char value[]) {
645 this.value = value;
646 this.offset = offset;
647 this.count = count;
648 }
It has been marked deprecated in Java 7 and being removed in Java 8. I was relying on some API that made calls to subSequence repeatedly, until I experienced a performance problem.
Digging into the code I saw that subSequence were using this constructor in Java 6. But as for now, it uses another one that copies the underlying array and start at the desired and ended offset, thus making it an O(1) operation to O(n).
Replacing the problematic call to subSequence has increased the performance by a factor of 10.
I was wondering why such a change was made. The only thing I am thinking of is that it could create potential memory leaks, for example:
String veryLargeString = ....;
String target = veryLargeString.substring(0, 10);
//assume I don't need anymore veryLargeString at this point
At that point the underlying char array can't be GC because it is still used by the target String. Thus you have in memory a large array but you only need the first 10 values of it.
Is this the only good use case or is there other reasons why this constructor has been removed?
Yes, String was changed significantly in Java 7 update 6 - now separate String objects never share an underlying char[]. This was definitely a trade-off:
Strings no longer need to maintain an offset and length (saving two fields per instance; not a lot, but it is for every string...)
One small string can't end up keeping a huge char[] alive (as per your post)
... but operations that were previously cheap now end up creating copies
In some use cases, the previous code would work better - in others, the new code would work better. It sounds like you're in the first camp, unfortunately. I can't imagine this decision was made lightly, however - I suspect that a lot of tests against different common work loads were made.

Representing a string uniquely using hashCode [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am trying to create a zookeeper node with unix path as values(like /x/home/rrs/data0) , but this is not allowed.
So I thought of generating a hash code of path and then use it to create a node.
But I read following about the hashcode:
Hash should not be used in a distributed application.
There might be collisions, For example, the Strings "Aa" and "BB" produce the same hashCode: 2112
Should i go ahead with hash code or What other options i have for my use case?
Also if i keep the string same all the time , is it guaranteed to generate same hashCode every time?
Yes, the same string will always generate the same hash-code.
Hash-codes do collide, the chance that similar (but different) strings will collide is just very very small (that's the generic idea). Your application should be able to recover (at least not break) from a collision.
What are the nature of the strings? Are they only letters? Maximum length? These properties can be used to generate a better hashcode. One of the nicest techniques I know of is Zobrist keys. Depending on the nature of your strings, this may be an option.
This depends on what you are trying to do.
But you're right: Java hashCodes are not designed to be collision free.
If you need some kind of unique identifier you could use a cryptographic hash function (like e.g. SHA-256, MD5 etc.) over your string.
If you just have a problem with some characters in your string just replace them e.g. with underscore.
Depending on what Zookeeper is/does perhaps hashCode is not a problem at all. EHCache uses it and it's perfectly fine there for distibuted hash tables.
It's a pitty, but hashCode of String really does generate the same hash code all the time for the same string. This is because it is documented and therefore cannot be changed. (But note: this doesn't include different representations of the same string like it's possible in unicode. But I think this is not a problem here.)

Obfuscation: hide hardcoded values in java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
hiding strings in Obfuscated code
I'm trying to hide a little some static Strings of my app in order to make it harder to decompile, this way like the constants like cipher algorithms names are harder to find in the obfuscated code.
I've considered things like:
String CONCAT= "concat"+"string";
String RAW_STRING= "raw_string";
String FROM_BYTES=new String("from_bytes".getBytes());
String FROM_CHARS=new String(new char[]{'f','r','o','m','_','c','h','a','r','s'});
String FROM_CHAR2=new String(new char[]{102,114,111,109,95,99,104,97,114,115,95,50});
And the last two options seems to be "darker" than the raw option but I imagine there are better ways for doing this.
How can I improve this? Thanks
For one, you shouldn't just write
String FROM_CHAR2=new String(new char[]{102,114,111,109,95,99,104,97,114,115,95,50});
It's a dead give-away that the char array is actually a String.
You can do a combination of the followings:
put your "String" in an int[] array
or even better, break your String into several int arrays
calculate/manipulate the array's values at various stage of the application, so its value will only become valid at a certain interval during a runtime, guaranteeing that it won't be deciphered at a curious glance by decompiling your code
passes the array(s) back and forth, through local variables, back to instance variables, etc, before finally converting the arrays to a single array to be passed to the String constructor
immediately set the String to null after use, just to reduce the amount of time the actual String exist at runtime
I would prefer to set the value in the static (class) initializer using an decryption algo
Something like
class ...
String CONCAT;
static {
CONCAT = uncrypt ("ahgsdhagcf");
}
where uncrypt might be really a good unencryption algo or somewhat weaker a base64 decode.
In any case you need a simple program to encode your string first.

Categories

Resources