B
B
Bogdan Pasechnik2013-03-20 23:32:45
PHP
Bogdan Pasechnik, 2013-03-20 23:32:45

Unique ID generation

Orders are constantly being created on the site. A unique id must be generated for each order. It should be simple enough for human perception and must not be repeated.
You can not use the id from the database and somehow navigate to it.
So far, I've come up with tying up to time () and partially converting it into numbers. For better readability.
Something like this
PHP code

$letters='QWERTYUIOPASDFGHJKLZXCVBNM1234567890';
$count=strlen($letters);
$intval=time();
$result='';
for($i=0;$i<4;$i++) {
        $last=$intval%$count;
        $intval=($intval-$last)/$count;
        $result.=$letters[$last];
}
echo $result.$intval;


as a result, I get something like this WKI0-811 code , I
add rand (10,99) to the end to eliminate duplication at the same second. I get this WKI0-811-45 The
code is long and complex. Dislikes 1. The possibility of dubbing, though very small. 2. The ending 811 rarely changes. Because it's roughly years from time().
Also I am sure that there are more beautiful solutions. Thank you for your attention

Answer the question

In order to leave comments, you need to log in

16 answer(s)
B
B7W, 2013-03-20
@B7W

There is a UUID standard. Make your own based on it.

B
BoShurik, 2013-03-21
@BoShurik

I am using this:

base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);

A
Alexey Vydrin, 2014-08-15
@alexvy

the easiest way is to take unix time, break it into groups of digits:
140-785-156
uniqueness with nine digits will last for 30 years
even if a competitor guesses how you get an ID - this will not help him in any way
UPD: The problem of uniqueness can be solved by modifying the key directly order table field - ALTER TABLE table_order AUTO_INCREMENT. mySql will keep track of its uniqueness

M
MikhailEdoshin, 2013-03-21
@MikhailEdoshin

One technique for generating non-consecutive unique numbers is to take a serial number and apply a masking operation to it, such as inverting given bits and then rearranging it in a fixed pattern. Let us have three-bit numbers from 0 to 7: 000, 001, 010, 011, 100, 101, 110, 111. First, invert the second bit: 010, 011, 000, 001, 110, 111, 100, 101. We get all the same numbers, but in a different order - 2, 3, 0, 1, 6, 7, 4, 5. Then, assuming that the bits are numbered 321, rearrange them to 132: 001, 101, 000, 100, 011, 111 , 010, 110 - 1, 5, 0, 4, 3, 7, 2, 6.
Maybe it makes sense to also add a checksum, even if the parity bit is 0010, 1010, 0001, 1001, 0110, 1110, 0101, 1101 or 2, 10, 1, 9, 6, 14, 5, 13. Numbers remain unique , and completely reversible, but spread over a larger range.

E
EugeneOZ, 2013-03-21
@EugeneOZ

Remove the strange prefix - it does not exclude duplicates at all and impairs readability. 4 characters will be enough for you, even if the store plans to sell goods to all the inhabitants of the planet several times (raise the number of characters in the code to the power of the number of possible characters, for example 4 ^ 20). And the uniqueness needs to be checked in the database and blocking until a new value is written there - this is a very serious moment, you should not be so negligent about it.

M
Max, 2013-03-21
@7workers

once I solved exactly the same problem, I came to the conclusion that the script generated guaranteed unique IDs and added them to the buffer, who needed to just take it from the buffer.

V
Vyacheslav Slinko, 2013-03-21
@KeepYourMind

What is wrong with autoincrement int?

N
nochkin, 2013-03-20
@nochkin

I would do the same, but not based on the time, but based on the id from the database.
That is, we do not shine the id itself according to the conditions of the task, and the result is always guaranteed to be unique.
You can also add the same rand(10.99) to it if you don't want the orders to follow each other exactly.

C
creage, 2013-03-21
@creage

I use this in my projects . Can be rewritten in any language.

S
Sergey, 2013-03-21
Protko @Fesor

stackoverflow.com/questions/4049455/how-to-create-a-uuid-in-php-without-a-external-library

S
strib, 2013-03-21
@strib

Why not a counter and inserting a delimiter every 3 digits?
With letters - you are tormented by phone taking order numbers ...
635-891
981-578-13
981-578-134

M
Max, 2013-03-21
@7workers

Encode the current date-time + IP address from which the order was received

A
afiskon, 2013-03-22
@afiskon

“The problem is that the mongo base is used where the id is 5149e333dffa825a03000047”
For example, like this. Take md5 from this id (as well as time, user IP, etc., if desired) and leave the first 8 characters. If they are already using it (which, however, is unlikely), take md5 from this id and rand() until you get a unique id.

R
Roman Danilov, 2013-03-23
@Infra_HDC

1. Try to think in the direction of using session_id () as one of the sources for hash generation - in addition to the already proposed source options.
2. If the received hashes are not human-readable, then why not store them somewhere in a separate table - the name of the HASH field to store the hash itself inside this table - and use an integer ID to generate the human-readable part of the id, i.e. key from this table?
3. Keeping such a table up to date
3.1. Each HASH value has a lifetime after which it is invalid, perhaps this time is stored in a separate field of this table in the timestamp format
3.2. After an ID has become invalid, there is a technological timeout after which the HASH field is cleared and the ID value can be reused, or the entry is removed entirely from table
3.3. Or, the application algorithm itself controls the irrelevance of the ID.
With the skillful implementation of such an economy, the number of records in the table and the maximum value of its ID should not be very many, and there should not be any special problems with human readability: upon receipt of orders, initially the IDs will be 0, 1 , 2, 3, 4, 5, ..., and when holes appear in the sequence, as a result of the removal of irrelevant IDs, intermediate values ​​between 1 and the maximum achieved ID value, because holes - vacant areas within an ordered set of ID values ​​- will be filled with new data.

P
Pavel Shevchuk, 2018-01-04
@pshevchuk1964

You can do this String iD = (YYYYMMDDhhmmssSSS + random(5) + checksum)

public void createUnicalNumber() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat format1 = new SimpleDateFormat("YYYYMMDDHHmmssSSS");
        cal.add( Calendar.DATE, (0) );
        String dataNew = format1.format( cal.getTime() );
        String dataAdd = createWord(5);
        String dataContr = contSumm(dataNew+dataAdd);
        do {
            dataContr = "0"+dataContr;
        } while (dataContr.length()<5);
        System.out.println( dataNew+dataAdd+dataContr );
    }

    private String contSumm( String str){
        int n_cont=0;
        for(int countStr =0; countStr<str.length();countStr++) {
            n_cont+=str.charAt( countStr );
    }
        String dxshxs=String.valueOf( n_cont );
        return dxshxs;
    }

    private String createWord (int l){
        String word ="";
        for (int x=0; x<l; x++ ) {
            int bukva = 65 +((int) Math.round(Math.random()*25));// 25 длина символьного ряда в кодовой таблице
            char one_char = (char) bukva;
            word +=  one_char;
        }
        return word;
    }

It looks like this: 20180104113747719XKSAN01261 ​​The
moment of formation is visible and supplemented with a checksum to eliminate a single error. This code can be checked. Write - I will answer how.

T
Tomarev, 2021-02-06
@Tomarev

The easiest way :)
$uniqueNum = crc32(uniqid());

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question