Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate unique 10 chars alphanumeric hashes in MySQL

I have a simple table with field called "hash" VARCHAR 10 UNIQUE FIELD

Now I would like to run a query and generate automatically the hashes inside the field.

The problem is that the hashes has to be alpha-numeric and has to be long 10 chars and UNIQUE.

table structure:

CREATE TABLE `vouchers` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `hash` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `hash` (`hash`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

So I need to INSERT hashes into hash field, they should look like random alphanumeric random hashes, I mean users shouldn't be able to catch the next or previous hash just looking at one hash, also they must be 10 chars long and unique.

Has anyone any clue for this?

like image 261
itsme Avatar asked Aug 31 '13 13:08

itsme


2 Answers

-- most elegant, has adjustable length 1-32 and probably has best performance
SELECT SUBSTR(REPLACE(UUID(),'-',''),1,10) as randomStringUUID
;

-- generate 10 character [a-z0-9] string, has adjustable letter/nr ratio
SELECT CONCAT(
  CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ,CASE WHEN RAND()>=0.5 THEN char(round(RAND()*9+48)) ELSE char(round(RAND()*25+97)) END
  ) as randomString
;

-- as bonus: generate a variable size letter only string, best for emulating names/words
SELECT SUBSTR(CONCAT(char(RAND()*25+55),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97),char(RAND()*25+97)),1,RAND()*9+4) as RandomName

Test at http://sqlfiddle.com/#!8/d41d8/586

like image 104
Stefan Rogin Avatar answered Sep 28 '22 15:09

Stefan Rogin


Here's the code to wrap Gordon's answer above into a function (credit to Gordon) -

delimiter |
create function hash10() returns varchar(10)
begin
declare chars varchar(36);
set chars = '0123456789abcdefghijklmnopqrstuvwxyz';
return concat(substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1),
              substring(chars, floor(rand()*36) + 1, 1)
             );
end|
delimiter ;

Then you can use...

insert into x (hash) values (hash10()),(hash10()),(hash10());
like image 26
zevra0 Avatar answered Sep 28 '22 14:09

zevra0