Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hashing a String to a Numeric Value in PostgreSQL

I need to Convert Strings stored in my Database to a Numeric value. Result can be Integer (preferred) or Bigint. This conversion is to be done at Database side in a PL/pgSQL function.

Can someone please point me to some algorithm or any API's that can be used to achieve this?

I have been searching for this on Google for hours now, could not find anything useful so far :(

like image 698
Salman A. Kagzi Avatar asked Mar 21 '12 17:03

Salman A. Kagzi


People also ask

How do I convert text to numeric in PostgreSQL?

Discussion: Use the :: operator to convert strings containing numeric values to the DECIMAL data type. In our example, we converted the string ' 5800.79 ' to 5800.79 (a DECIMAL value). This operator is used to convert between different data types.

What is hashing in PostgreSQL?

PostgreSQL's hash function maps any database value to a 32-bit integer, the hash code (about 4 billion possible hash codes). A good hash function can be computed quickly and "jumbles" the input uniformly across its entire range. The hash codes are divided to a limited number of buckets.

Can I hash a string?

For the conversion, we need a so-called hash function. The goal of it is to convert a string into an integer, the so-called hash of the string. The following condition has to hold: if two strings and are equal ( ), then also their hashes have to be equal ( hash ( s ) = hash ( t ) ).

How do I hash a column in PostgreSQL?

Use a trigger to set the hash column on insert and update. For SHA-256, use the pgcrypto extension module's digest function. Since you haven't specified your PostgreSQL version I'll assume you're using the current 9.2 in the following examples. Note that the CREATE EXTENSION function must be run as a superuser.


2 Answers

Just keep the first 32 bits or 64 bits of the MD5 hash. Of course, it voids the main property of md5 (=the probability of collision being infinitesimal) but you'll still get a wide dispersion of values which presumably is good enough for your problem.

SQL functions derived from the other answers:

For bigint:

create function h_bigint(text) returns bigint as $$  select ('x'||substr(md5($1),1,16))::bit(64)::bigint; $$ language sql; 

For int:

create function h_int(text) returns int as $$  select ('x'||substr(md5($1),1,8))::bit(32)::int; $$ language sql; 
like image 69
Daniel Vérité Avatar answered Sep 24 '22 17:09

Daniel Vérité


You can create a md5 hash value without problems:

select md5('hello, world'); 

This returns a string with a hex number.

Unfortunately there is no built-in function to convert hex to integer but as you are doing that in PL/pgSQL anyway, this might help:

https://stackoverflow.com/a/8316731/330315

like image 20
a_horse_with_no_name Avatar answered Sep 24 '22 17:09

a_horse_with_no_name