Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 602
  • Last Modified:

How to turn a large number into a shorter one with letters

Hello,

I'm generating an order number based on the unix timestamp and a random number added to the end to make sure that it is a globally unique number.

The number ends up being really long and I would like to put some letters in it.

Is there a good way to take the generated numbers and convert it to something shorter with letters in it.  Or a better way to generate a unique identifier with letters.  I used the unix time since it makes sure that all orders have a different number.

Here is a sample number:
6134713354211947

thanks!!
0
parlays
Asked:
parlays
7 Solutions
 
kiwistagCommented:
Unfortunately as soon as you say turn it to the likes of say a scientific notation it fits outside the boundaries of a number and falls as a varchar.
You could try a root derivative maybe?

See below for others who have had similar issues.

0
 
Jaime OlivaresCommented:
You can use base-36 or base-64 encoding.
PHP has a ready-made function for base-64 called base64_encode (http://php.net/manual/en/function.base64-encode.php) but unfortunately it may produce a string larger than the original, so I suggest to use base_convert (http://php.net/manual/en/function.base-convert.php) instead for base-36 conversion:

$returnValue = base_convert('6134713354211947', 10, 36);
// Result string is: 1oekoephqp7
0
 
DaemonBarberCommented:
you could convert the decimal to hex...?
it would give you a shorter number string containing letters.
use the dechex() and hexdec() functions to convert between the two.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Cornelia YoderArtistCommented:
do{
        $id=rand()%1000000000;
        $result=mysql_query("Select * from MyTable where id=$id;",$conn);
}while(mysql_num_rows($result)>0);


This will simply generate a random id, then check to make sure it is not in the table already.  


As long as your random number size is sufficiently large, the chance of a duplicate being generated for a second order while the first order is being processed approaches zero.
0
 
Ray PaseurCommented:
Unfortunately the UNIX timestamp will not necessarily be unique.  Two orders might arrive at the same second.

You might make the md5() string of the UNIX timestamp, plus the product, plus the IP address plus your salt string.  That would almost certainly be unique.  Store this string in a VARCHAR(32) column.
http://us3.php.net/manual/en/function.md5.php

Another way to make a unique key is shown in the code snippet.

<?php // RAY_random_unique_string.php
error_reporting(E_ALL);
echo "<pre>";

// GENERATE A SHORT UNIQUE RANDOM STRING FOR USE AS SOME KIND OF KEY
// WE DELIBERATELY OMIT LOOK-ALIKE LETTERS LIKE O and 0, I and 1.
// NOTE THAT THE DATA BASE MUST HAVE THE rand_key FIELD DEFINED AS "UNIQUE"
// NOTE THAT THE LENGTH ARGUMENT MUST MATCH THROUGHOUT SO WE DEFINE() IT.

define('ARG_LENGTH', 6);

// CONNECTION AND SELECTION VARIABLES FOR THE DATABASE
$db_host = "??"; // PROBABLY 'localhost' IS OK
$db_user = "??";
$db_word = "??";
$db_name = "??";

// OPEN A CONNECTION TO THE DATA BASE SERVER
// MAN PAGE: http://php.net/manual/en/function.mysql-connect.php
if (!$db_connection = mysql_connect("$db_host", "$db_user", "$db_word"))
{
    $errmsg = mysql_errno() . ' ' . mysql_error();
    echo "<br/>NO DB CONNECTION: ";
    echo "<br/> $errmsg <br/>";
}

// SELECT THE MYSQL DATA BASE
// MAN PAGE: http://php.net/manual/en/function.mysql-select-db.php
if (!$db_sel = mysql_select_db($db_name, $db_connection))
{
    $errmsg = mysql_errno() . ' ' . mysql_error();
    echo "<br/>NO DB SELECTION: ";
    echo "<br/> $errmsg <br/>";
    die('NO DATA BASE');
}
// IF WE GOT THIS FAR WE CAN DO QUERIES


// FUNCTION TO CREATE A DATABASE TABLE
function create_myTable()
{
    $length = ARG_LENGTH;

    mysql_query("DROP TABLE myTable");
    $psql
    =
    " CREATE TEMPORARY TABLE myTable
    ( _key        INT(8)            NOT NULL AUTO_INCREMENT
    , rand_key    VARCHAR($length)  UNIQUE NOT NULL DEFAULT '?'
    , PRIMARY KEY(`_key`)
    ) ENGINE=INNODB DEFAULT CHARSET=ascii
    "
    ;
    if (!mysql_query($psql)) die( "FAIL: $psql <br/>" . mysql_error() );
}


// FUNCTION TO MAKE A RANDOM STRING
function random_string()
{
    //     1...5...10...15...20...25...30......
   $alphabet = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
   $string   = "";
   while(strlen($string) < ARG_LENGTH)
   {
       $string .= substr($alphabet, mt_rand(0,(strlen($alphabet))), 1);
   }
   return($string);
}


// FUNCTION TO ENSURE THE RANDOM STRING IS UNIQUE
function make_random_key()
{
    $rand_key = '';

    // GENERATE A UNIQUE AND RANDOM TOKEN
    while ($rand_key == '')
    {
        $rand_key = random_string(ARG_LENGTH);
        $isql     = "INSERT INTO myTable ( rand_key ) VALUES ( '$rand_key' )";

        // IF QUERY ERROR
        if (!mysql_query($isql))
        {
            $err = mysql_errno();

            // DUPLICATE UNIQUE FIELD ON rand_key
            if ($err == 1062)
            {
                // ACTIVATE THIS TO VISUALIZE KEY COLLISIONS
                // echo PHP_EOL . $rand_key;

                // NULLIFY THIS KEY AND TRY AGAIN
                $rand_key = '';
            }

            // OTHER QUERY ERROR
            else
            {
                /* HANDLE FATAL QUERY ERROR ($isql) */
            }
        }
    }
    return $rand_key;
}


// SHOW HOW TO MAKE LOTS OF UNIQUE AND RANDOM STRINGS
create_myTable();

$kount = 0;
$array = array();
while ($kount < 100)
{
    $array[] = make_random_key();
    $kount++;
}

print_r($array);

Open in new window

HTH, ~Ray
0
 
Kyle HamiltonData ScientistCommented:
what about creating an auto incrementing primary key in the database to use as the order number. this will always be unique.
0
 
Slick812Commented:
greetings : parlays , , Guaranteeing a Unique ID is not so easy , but there is a php function that is suppose to do that see uniqid( ) function in the manual at -
http://www.php.net/manual/en/function.uniqid.php

I have seen several that say the php function microtime( ) can give a fine enough difference to almost Guarantee a unique number, so I'll use that for a number base -

in the code below I chop off the first two characters in the microtime string, since They rarely ever change.
next I convert the numbers to Capital Letters, by simply shifting them up the ascii order 20 places, next I
add a single random character to the beginning to help it be unique, The unique ID will be in the $mt2 string.

$mt = ''.microtime(true);
$mt = str_replace('.', '', $mt);// remove the period
$mt2 = substr($mt,2);// chop off first two
$e = strlen($mt2);
for ($i = 0; $i <$e; ++$i) $mt2{$i} = chr(ord($mt2{$i})+20);// convert numbers
$mt2= chr(mt_rand(65,89)).$mt2;// add random
echo 'UNIQUE ID',strlen($mt),' microtime= ',$mt,' mt2= ',$mt2,'<br />';

Open in new window


Maybe you can get something from this?
0
 
OrcbighterCommented:
You state
...and I would like to put some letters in it.

this implies that you want an alpha-numeric key, which is a string in coding and a varchar in SQL Server, or Oracle, etc.
Note: If you are going to use alpha keys in a database like SQL Server, it would be a good idea to ensure it was installed with binary collation.

How big does the number have to be? For example, how many entries will be made in, say, a year?
Would it exceed MaxInt, ie 2^31 (-2,147,483,648 to +2,147,483,647 signed, or 0 to 4,294,967,295 unsigned)?

If, I go on the assumption that you will not exceed MaxInt new entries in a given year, then it is easy to create a unique identifier.
You could stay with numbers and convert them to chars, so the number 2012345, would be stored as '2' '0' '1' '2' '3' '4' '5'

Now the numbering system would be to add two digits to the start of the number. This would be the last two digits of the year, in this case 12, then just append the three-digit Julian-Day number, and then append a unique and incrementing integer, zero-filled to however many places you need.
Thus, for September 12, 2012, for the 32nd entry, the number would be:
12+256+00000000032
The next entry would be: 12+256+00000000033
In this way, you never run out. The first two numbers for the year is good right up to 2099.
0
 
parlaysAuthor Commented:
thanks so much everyone!
0
 
Slick812Commented:
OK, glad you got something to work, After I posted here last time, I got to consider that the mt_rand( ) is seeded with a server time stamp, so It likely will not be different with the same microtime( ), and according to some, it is possible in muti-processor servers to get the same microtime( ) , , so I did this to get a unique ID, instead of any call to get a random, I get the IP from $_SERVER['REMOTE_ADDR'], which will probally be different if the microtime( ) is identical.  AND I looked up a neat function to shorten an integer string, it's -
base_convert($uID, 10, 36);
you might use it to get a shorter string for integer strings.

below is the code for the makeUID($noNum = false)  function, which always outputs an eleven character string.
if you set the $noNum  to true it will have NO integers in the string just a-z in lower and Caps

function makeUID($noNum = false) {
	$ip = $_SERVER['REMOTE_ADDR'];
	if (strlen($ip)<2) $ip = '91'; else {
		$ip = str_replace('.', '', $ip);
		$ip=substr($ip,strlen($ip)-2);
		}
	$mt = microtime(false);
	$uID=substr($mt,2,6);
	$mt=substr($mt,13);
	$as4 = (int) $ip{1};
	$as2 = (int) $uID{5};
	$e2 = $as2+$as4;
	$uID=$mt.$ip.$uID;
	$k2 = array('6','3','7','4','9','5','4','8','3','8','7','4','5','9','3','8','6','5','3');
	$uID{0}= $k2[$e2];
	$uID=base_convert($uID, 10, 36);
	if ($noNum) $uID = strtr($uID, '01234567890', 'VBMDPFUHWR');
	return $uID;
}

$uID = makeUID();
$uID2 = makeUID(true);
echo strlen($uID),'=length, uID= ',$uID,' , uID2= ',$uID2,'<br />';

Open in new window


I believe this will have a very very high probability to generate unique strings
0
 
parlaysAuthor Commented:
You are the man!  I appreciate you taking the time with those write-ups, I learned a lot.  Thanks!!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now