0

I'm trying to store all possible combinations of 4 letters from [Aa-Zz]. The problem is that I've got error 500 when I try to use the function below. When I try with a simple string it is working.

Here is the code that I have so far

function print_combinations($characters, $length, $combination = '') {
    foreach ($characters as $i) {
        print_combinations($characters, $length - 1, $combination . $i);
    }
}

$characters = array_merge(range('A', 'Z'), range('a', 'z'));

$filename = 'test.txt';
$combos = print_combinations($characters, 4);

if (is_writable($filename)) {

    if (!$fp = fopen($filename, 'a')) {
         echo "Cannot open file ($filename)";
         exit;
    }
    
    if (fwrite($fp, $combos) === FALSE) {
        echo "Cannot write to file ($filename)";
        exit;
    }

    echo "Success, wrote ($combos) to file ($filename)";

    fclose($fp);

} else {
    echo "The file $filename is not writable";
}

If I change

$combos = print_combinations($characters, 4);

to

$combos = "some text;

it is working fine. So the problem is in how I call the function probably.

Any suggestions on this?

S.I.
  • 3,250
  • 12
  • 48
  • 77
  • Just "Error 500"? No actual error? Is there more info in your php log? – JNevill Aug 08 '22 at 18:28
  • Yes, just `Internal Server Error` and there is nothing in error.log. It is shared hosting and I'm unable to check another logs. – S.I. Aug 08 '22 at 18:30
  • I'm no php expert, but you may be bumping into `fwrite()` file limit size: https://stackoverflow.com/questions/33500998/php-fwrite-for-writing-a-large-string-to-file. I'm thinking this number of combos (52*52*52*52) is going to be in the 7.5mb-8mb range. – JNevill Aug 08 '22 at 18:30
  • I have tried with `ini_set('memory_limit', '8192M');` at the top but still `error 500` – S.I. Aug 08 '22 at 18:37
  • Rather than attempting the full gamut of `A-Z,a-z` does this work with a smaller range, say `A-C` and `a-c`?? – Professor Abronsius Aug 08 '22 at 18:44
  • Nope, still the same error. – S.I. Aug 08 '22 at 18:46

1 Answers1

0

Looking for something like this?

<?php

$filename = 'test.txt';

if (is_writable($filename) && ! $fp = fopen($filename, 'ab')) {
    echo "Cannot open file ($filename)";
    exit;
}

$characters = [
    array_merge(range('A', 'Z'), range('a', 'z')),
    array_merge(range('A', 'Z'), range('a', 'z')),
    array_merge(range('A', 'Z'), range('a', 'z')),
    array_merge(range('A', 'Z'), range('a', 'z')),
];

$counts = array_map("count", $characters);
$total  = array_product($counts);

$combinations = [];
$curCombs     = $total;

foreach (array_keys($characters) as $field) {
    $curCombs            /= $counts[$field];
    $combinations[$field] = $curCombs;
}

$counter = 0;

for ($i = 0; $i < $total; $i++) {
    $test = [];
    foreach ($characters as $field => $value) {
        $test[$field] = $value[(int) ($i / $combinations[$field]) % $counts[$field]];
    }

    if (! fwrite($fp, implode($test))) {
        echo "Cannot write to file ($filename)";
        exit;
    }
    ++$counter;
}

echo "Success, wrote ($counter) to file ($filename)";
Guido Faecke
  • 644
  • 1
  • 3
  • 7
  • Well yes, got `Success, wrote (7311616) to file (test.txt)`. Can you put some explanation on the `foreach (array_keys($characters) as $field) {}` and `$test[$field] = $value[(int) ($i / $combinations[$field]) % $counts[$field]];` because I'm not sure what they do – S.I. Aug 08 '22 at 18:59
  • Not exactly... I copied/pasted/modified this one together from different examples and a lot of try & error. ;) – Guido Faecke Aug 08 '22 at 19:03
  • 1
    @Goro $characters has 4 elements, all with the same array: A, B... Y, Z, a, b... y, z. So, 52 elements each. $counts has also 4 elements [52, 52, 52, 52] (the counts). $total isevery element of $counts multiplied, equivalently to 52**4. So, array_keys($characters) get the keys (0, 1, 2, 3, the indexes) and return as $field. – user19513069 Aug 08 '22 at 19:43
  • 1
    @goro $combinations is an array with 4 elements, where every element is total (`52**4` or `7311616`) divided by (52). So, `$combinations = [0 => 52**3, 1 => 52**2, 2 => 52, 3 => 1]`. Knowing that, for the second part: $i is the index from 0 to `52**4-1`. `($i / $combinations[$field])` is `$i / 52**3`, then `$i / 52**2`, then `$i / 52` and then `$i / 1` (= $i). But, since there's an `% $counts[$field]` (which is always 52), it's clamped to always be less than 52. So, it's generating numbers from 0 to `52**4` and then kinda-of similar to converting to base 52, but using A-Za-z as characters. – user19513069 Aug 08 '22 at 20:01