3

I need generate codes from this letters

$a = array(
 'B','C','D','F','G','H','J','K','L','M','N','O',
 'P','Q','R','S','T','V','W','X','Y','Z','1','2',
 '3','4','5','6','7','8','9','0'
);

But there are 2 conditions: every code must be unique and contains 10 letters. I don't want to get random because is unefficient. Instead, I want go for every letter e.g.:

  1. BBBBBBBBBB
  2. BBBBBBBBBC
  3. BBBBBBBBBD

and so on.. Any ideas?

Niko
26.8k9 gold badges97 silver badges112 bronze badges
asked Aug 24, 2012 at 8:24
2
  • Why not just use something like uniqid? I can guarantee that that will be far more efficient than building the string yourself. Commented Aug 24, 2012 at 8:28
  • I need to generate 1,6mln codes and save them to data base. How to use uniqid? Commented Aug 24, 2012 at 8:31

4 Answers 4

4

I think that what you actually want is a list of sequential numbers (therefore not random at all) with a rather unconvetional base system. So BBBBBBBBB is 0, while BBBBBBBC is 1. This isn't hard to do, but obviously you have to code it yourself. Something like this might work:

function generate($num) {
 $num = base_convert($num, 10, 32); // convert the number to base 32
 $num = str_pad($num, 10, "0", STR_PAD_LEFT); // pad it with zeros to the left
 $num = str_replace(array(
 '0','1','2','3','4','5','6','7','8','9','a','b',
 'c','d','e','f','g','h','i','j','k','l','m','n',
 'o','p','q','r','s','t','u','v'
 ), array(
 'B','C','D','F','G','H','J','K','L','M','N','O',
 'P','Q','R','S','T','V','W','X','Y','Z','1','2',
 '3','4','5','6','7','8','9','0'
 ), $num); // replace the normal characters with your custom array
 echo $num, "\n";
}
for ($i = 0; $i < 10; $i++) generate($i);

Obviously you could change the 10 in the for statement to whatever you liked, and insert into a database rather than echoing. Obviously 1.6m records would take some time to generate.

The above code gives the following output:

BBBBBBBBBB
BBBBBBBBBC
BBBBBBBBBD
BBBBBBBBBF
BBBBBBBBBG
BBBBBBBBBH
BBBBBBBBBJ
BBBBBBBBBK
BBBBBBBBBL
BBBBBBBBBM
answered Aug 24, 2012 at 8:49
Sign up to request clarification or add additional context in comments.

4 Comments

Clever solution, but quite slow
@PeterSzymkowski Well yes. But let's face it: if speed is the objective, the solution is to use plain old numbers.
+1 for this, definitely the most simplistic answer that gets the job done. One thing to consider (and this applies to any approach) is that you would need to store this in the database on the fly, as filling an array with the generated values will consume insane amounts of memory.
Incredibly @PeterSzymkowski's solution is more than 6 times faster on my dev machine, though.
3
<?php
$length = 3;
$letters = str_split("ABC"); // define your dictionary here
$index = array_fill(0, $length, 0);
$key = $length - 1;
while(true) { 
 $code = "";
 for($i=0;$i<$length;$i++) { 
 $code .= $letters[$index[$i]]; 
 }
 echo $code ."<br/>"; // output code
 $index[$key]++;
 while(!isset($letters[$index[$key]])) {
 $index[$key] = 0;
 $key--;
 if($key < 0) {
 break 2;
 } 
 $index[$key]++;
 } 
 $key = $length - 1; 
}

Example:

answered Aug 24, 2012 at 8:44

2 Comments

Good solution, but replace: $index = Array(); for($i=0;$i<$length;$i++) { $index[$i] = 0; } by $index = array_fill(0, $length, 0); -
For what it's worth, here is a codepad with the format and dictionary requested by the OP. This is indeed significantly (5 to 10 times) faster than my solution, so a big +1.
1
<?php
$a = array(
 'B','C','D','F','G','H','J','K','L','M','N','O',
 'P','Q','R','S','T','V','W','X','Y','Z','1','2',
 '3','4','5','6','7','8','9','0'
);
function key_increment (&$symbols, $position = null) 
{
 global $a;
 if ($position === null) $position = count($symbols) - 1;
 if ($position == -1) return;
 $index = $symbols[$position];
 $index ++;
 if (!isset($a[$index])) {
 $v = 0;
 key_increment ($symbols, $position-1);
 }
 $symbols[$position] = $value;
}
function generate($length, $total) 
{
 global $a;
 $symbols = array_fill(0, $length, 0);
 for ($i = 0; $i < $total; $i ++) {
 $code = '';
 foreach ($symbols as $index) {
 $code .= $a[$index];
 }
 echo $code;
 echo '<br />';
 key_increment($symbols);
 }
}
generate(3, 100);
answered Aug 24, 2012 at 8:47

2 Comments

@PeterSzymkowski, yes, but it's cleary show how it must work. lonesomeday's questions is prefer
This code evidently works, but it's rather hard to follow. Do you think you could use descriptive variable names, rather than $s, $v, etc.?
0

It's probably best that you just use uniqid, especially seeing as you said you'll be generating 1.6 million codes . If you're concerned about the case, just use strtoupper()

echo strtoupper(uniqid());

Generating all of these and inserting them is going to take a fair bit of time.

answered Aug 24, 2012 at 8:37

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.