reversing a hash to it's string in solidity - hash

hello I am trying to save the physical address of somewhere in my contract but I found out
that large strings will cost more gas, so I am trying to save the string as a hash, and whenever I want, reverse that hash and get the string which I hashed.
Q1: is it possible?
Q2: if not, have you got any idea to save a large string with the lowest possible gas usage?
bytes32 x = keccak256("some large string");
function reverse (x) pure public returns(string memory){
string memory reversed = "here I want to unhash the x somehow !!";
return y;
}
output = some large string

1
No, it's not possible, hash functions are one way, and there's also a chance that 2 different inputs may conclude the same hash output. Hashes are meant to check if the integrity of a message, for example, if a string was modified during a process, by comparing their hashes ( the original string's hash and the received string's hash ).
2
MOST optimal way of storing big chunks of data is by using IPFS, a blockchain focused on data storage, then, in your smart contract what you'll store is a link to an IPFS file, this is usually how NFTs work since they don't store the literal data (png if its a monkey picture, XML or JSON if its credentials or certificates ) in the smart contract because that data its too big and it costs too much gas to read.
Anyway, if you still want to keep your string in your smart contract, the most optimal way would be the use a fixed array of bytesXX because string is a dynamic array of bytes. And if you won't modify that string at all, make it constant so the declaration will be inlined by the compiler, and it won't use storage.

Related

Is it SAFE to use partial MongoDB Id Key

I'm developing one system, where Badges will be created with a QRCode for each User, and I need to read that QRCode and show specific information to the user on the public screen.
QRCode reading is a little 'tricky'. When I did something like this, I was using MySQL with enumerated Ids (1, 100, 2304, 9990)... Witch is only about 5 characters.
However, MongoDB keys (DB that I'm using now) consists of a biggg key such as 52d35bf26bda8a5c8f8a22a8 witch has MANY characters.
What is the problem with that: QRCode becomes larger (more data, bigger the size), and becomes harder to read it fast on the WebCam (even in HD).
So, here is my idea: Use part of the Id, So that: 52d35bf26bda8a5c8f8a22a8 becomes perhaps 52d35bf26bd.
The question is really simple: Can I safely use the partial ID Key, without having re-occurrences? The maximum elements I will have, will be about 1000 order.
The question has has nothing to do with QRCode, but it explains the reason why I'm doing it.
ObjectId is a 12-byte BSON type, constructed using:
a 4-byte value representing the seconds since the Unix epoch,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter, starting with a random value.
Once known that, it depends on the part of the objectId you choose and how many time will pass between the insertions.
Regards
Regardless of whether it's safe or not, the size difference between the QR codes isn't that great.
Using the full string will get you an image like:
Using half the characters produces a code like:
I would suggest that even the cheapest smartphone would be able to scan the larger of the two images - it's not very complex at all.
Yes, you can safely compress a long hexadecimal string into a higher base to get fewer characters while retaining the same value.
Example:
Hex: 52d35bf26bda8a5c8f8a22a8
Base64: UtNb8mvailyPiiKo
The same idea can be taken further by using binary or even Chinese pictograph characters instead of base64.
This concept can be tested using a Numeral Base Converter Tool.

What kind of encrypted data is this?

A friend of me ask this, and i was thinking of asking this here too..
"What kind of data are this, how are they encrypted, or decrypted?"
My friend told me he got this from facebook.
d9ca6435295fcd89e85bd56c2fd51ccc
It looks like it could be an md5 hash.
Basically a hash is a one-way function. The idea is that you take some input data and run it through the algorithm to create a value (such as the string above) that has a low probability of collisions (IE, two input values hashing to the same string).
You cannot decrypt a hash because there is not enough information in the resultant string to go back. However, it may be possible for someone to figure out your input values if you use a 'weak' hashing algorithm and do not do proper techniques such as salting a hash, etc.
I don't know how FaceBook uses hashes, but a common use for a hash might be to uniquely identify a page. For example, if you had a private image on a page, you might ask to generate a link to the image that you can email to friends. That link might use a hash as part of the URL since the value can be computed quickly, is reasonably unique, and has a low probability of a third party figuring it out.
This is actually a large topic that I am by no means doing justice to. I suggest googling around for hash, md5, etc to learn more, if you are so inclinded.
It is a sequence of 128 bits, encoded as a lower-case hex string.
If you are talking about a Facebook API key, there is no deeper meaning to decode from the bits. The keys are created at random by Facebook and assigned to a particular application to identify it. Each application gets a different set of random bits for its API key.
This appears the be the...
hexadecimal representation for...
- ... a 16 bytes encryption block or..
- ... some 128 bits hash code or even
- ... just for some plain random / identifying number.
(Hexadecimal? : note how there are only 0 thru 9 digits and a thru f letters.)
While the MD5 Hash guess suggested by others is quite plausible, it could be just about anything...
If it is a hash or a identifying / randomly assigned number, its meaning is external to the code itself.
For example it could be a key to be used to locate records in a database, or a value to be compared with the result of the hash function applied to the user supplied password etc.
If it is an encrypted value, its meaning (decrypted value) is directly found within the code, but it could be just about anything. Also, assuming it is produced with modern encryption algorithm, it could take a phenomenal amount of effort to crack the code (if at all possible).

how can get original value from hash value?

My original Text : "sanjay"
SHA-1 Text : "25ecbcb559d14a98e4665d6830ac5c99991d7c25"
Now how can i get original value - "sanjay" from this hash value ?
is there any code or algorithm or method?
No. That's usually the point -- the process of hashing is normally one-way.
This is especially important for hashes designed for passwords or cryptology -- which differ from hashes designed, for say, hash-maps. Also, with an unbounded input length, there is an infinite amount of values which result in the same hash.
One method that can be used is to hash a bunch of values (e.g. brute-force from aaaaaaaa-zzzzzzz) and see which value has the same hash. If you have found this, you have found "the value" (the time is not cheap). "Rainbow tables" work on this idea (but use space instead of time), but are defeated with a nonce salt.
From what I've been taught on the subject, if you were the one that turned your value into a hash value, chances are you have full access to the hash function, and would be able to reverse it in the same way. If you only have the original value and the end value, and don't know what hash function was used, you can't really reverse it without doing what was said above (going over every possibility).

How do I access random element in a Perl DBM hash?

I have a Perl DBM hash containing a list of URLs that I want to pick randomly from to load balance spidering sites. As a result I want to pick a key at random, or select the nth element (so I can randomise n).
I'm aware this goes against the concept of a hash, but is this possible?
NOTE: missed a valuable point that hash size will be too large to load all the keys to randomly select.
I don't think any of the DBM packages have an API for retrieving a random key, or for retrieving keys by index number. You can look up a particular key, or you can read through all the keys in whatever order the database chooses to return them in (which may change if the database is modified, and may or may not be "random" enough for whatever you want to do).
You could read through all the keys and pick one, but that would require reading the entire database each time (or at least a sizable chunk of it), and that's probably too slow.
I think you'll need to rearrange your data structure.
You could use a real SQL database
(like SQLite), so you could
look up rows both by a sequential
row number and by URL. This would
be the most flexible.
You could use a sequential integer
as the key for your DBM file. That
would make picking a random one
easy, but you could no longer look
up entries by URL.
You could use two DBM files: the one you have now and a second keyed by sequential integer with the URL as value. (Actually, since URLs don't look like integers, you could store both sets of records in the same DBM file, but that would complicate any code that uses each.) This would use twice the disk space, and would make inserting/removing entries a bit more complicated. You'd probably be better off with approach #1, unless you can't install SQLite for some reason.
Picking a random element from an array is simpler so you can use keys(%foo) to get the array of keys and pick randomly from that.
I believe this will return a random element $x from an array:
$x = $array[rand #array];
If you want to shuffle an array, consider List::Util::shuffle. See http://search.cpan.org/perldoc/List::Util#shuffle_LIST
Of course, it is possible. First, get a list of the keys. Then, randomize the list, using shuffle from List::Util.
Then, loop over the keys.
If there are too many keys (so keeping them all in a list and shuffling is not possible), just remember that you are using tied hashes. Just use each to iterate over key value pairs.
The order will be deterministic but AFAIK, it will not be alphabetical or order of insertion. That, by itself, might be able to get you what you want.
You could use DBM::Deep instead of a traditional DB file to keep your data.
tie %hash, "DBM::Deep", {
file => "foo.db",
locking => 1,
autoflush => 1
};
# $hash{keys} = [ ... ]
# $hash{urls} = { ... } <- same as your current DB file.
my $like_old = $hash{urls}; # a ref to a hash you can use like your old hashref.
my $count = #{$hash{keys}};
With that you can pull out random values as needed.

What is hash exactly?

I am learning MD5. I found a term 'hash' in most description of MD5. I googled 'hash', but I could not find exact term of 'hash' in computer programming.
Why are we using 'hash' in computer programming? What is origin of the word??
I would say any answer must be guesswork, so I will make this a community wiki.
Hash, or hash browns, is breakfast food made from cutting potatoes into long thin strips (smaller than french fries, and shorter, but proportionally similar), then frying the mass of strips in animal or vegetable fat until browned, stuck together, and cooked. By analogy, 'hashing' a number meant turning it into another, usually smaller, number using a method which still deterministically depending on the input number.
I believe the term "hash" was first used in the context of "hash table", which was commonly used in the 1960's on mainframe-type machines. In these cases, usually an integer value with a large range is converted to a "hash table index" which is a small integer. It is important for an efficient hash table that the "hash function" be evenly distributed, or "flat."
I don't have a citation, that is how I have understood the analogy since I heard it in the 80's. Someone must have been there when the term was first applied, though.
A hash value (or simply hash), also
called a message digest, is a number
generated from a string of text. The
hash is substantially smaller than the
text itself, and is generated by a
formula in such a way that it is
extremely unlikely that some other
text will produce the same hash value.
You're refering to the "hash function". It is used to generate a unique value for a given set of parameters.
One great use of a hash is password security. Instead of saving a password in a database, you save a hash of the password.
A hash is supposed to be a unique combination of values from 00 to FF (hexadecimal) that represents a certain piece of data, be it a file or a string of bytes. It is used primarily for password storage and verification, and to test if a file is the same as another file (i.e. you hash two files, if they match, they're the same file).
Generally, any of the SHA algorithms are preferred over MD5, due to hash collisions that can occur when using it. See this Wikipedia article.
According to the Wikipedia article on hash functions, Donald Knuth in the Art of Computer Programming was able to trace the concept of hash functions back to an internal IBM memo by Hans Peter Luhn in 1953.
And just for fun, here's a scrap of overheard conversation quoted in Two Women in the Klondike: the Story of a Journey to the Gold Fields of Alaska (1899):
They'll have to keep the hash table going all day long to feed us. 'T will be a short order affair.
the hash function hashes input to a value, requires a salt value and no proof salt is needed to store. Indications are everybody says we must store the salt same time match and new still work. Mathematically related concept is bijection
adding to gabriel1836's answer, one of the important properties of hash function is that it is a one way function, which means you cannot generate the original string from its hash value.