From 166271461beaff44fb7ab1ae385fb2267360a4e7 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Mon, 13 Mar 2017 03:29:02 +0000 Subject: [PATCH 01/72] Rename alphanumeric-generator.php to v.0.1/alphanumeric-generator.php --- alphanumeric-generator.php => v.0.1/alphanumeric-generator.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename alphanumeric-generator.php => v.0.1/alphanumeric-generator.php (100%) diff --git a/alphanumeric-generator.php b/v.0.1/alphanumeric-generator.php similarity index 100% rename from alphanumeric-generator.php rename to v.0.1/alphanumeric-generator.php From 76d15ba3c1fe8272bdcf545404ec4f2cb18b1ad4 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Mon, 13 Mar 2017 03:31:05 +0000 Subject: [PATCH 02/72] Rename examplo.php to v.0.1/examplo.php --- examplo.php => v.0.1/examplo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename examplo.php => v.0.1/examplo.php (99%) diff --git a/examplo.php b/v.0.1/examplo.php similarity index 99% rename from examplo.php rename to v.0.1/examplo.php index 67faa9f..2c3ecd4 100644 --- a/examplo.php +++ b/v.0.1/examplo.php @@ -27,4 +27,4 @@ } -?> \ No newline at end of file +?> From f99b696c11f0375673de5840382aeefcd16cef4c Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Mon, 13 Mar 2017 03:35:16 +0000 Subject: [PATCH 03/72] Rename alphanumeric-generator.php to v.0.1/alphanumeric-generator.php --- alphanumeric-generator.php => v.0.1/alphanumeric-generator.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename alphanumeric-generator.php => v.0.1/alphanumeric-generator.php (100%) diff --git a/alphanumeric-generator.php b/v.0.1/alphanumeric-generator.php similarity index 100% rename from alphanumeric-generator.php rename to v.0.1/alphanumeric-generator.php From e71a79542f5ebcbb4c5d6e653654374f24bd8609 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Mon, 13 Mar 2017 03:40:46 +0000 Subject: [PATCH 04/72] Create UniqueKey.php --- v.0.3/UniqueKey.php | 199 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 v.0.3/UniqueKey.php diff --git a/v.0.3/UniqueKey.php b/v.0.3/UniqueKey.php new file mode 100644 index 0000000..e6f6311 --- /dev/null +++ b/v.0.3/UniqueKey.php @@ -0,0 +1,199 @@ +default_code_length = $SetLength; + } + } + + public function SetType($SetType=FALSE){ + if(is_numeric($SetType) AND $SetType>=2 AND $this->code_max_type>=$SetType){ + $this->default_code_type = $SetType; + } + } + + public function CodeCountRange($code_char_range=[]){ + $count_characters = count($code_char_range); + return pow($count_characters, $this->default_code_length); + } + + public function CodeTypes(){ + + $CodeTypes[1]['code_name'] = '[A-Z]'; + $CodeTypes[2]['code_name'] = '[a-z]'; + $CodeTypes[3]['code_name'] = '[A-Z,a-z]'; + $CodeTypes[4]['code_name'] = '[0-9]'; + $CodeTypes[5]['code_name'] = '[A-Z,0-9]'; + $CodeTypes[6]['code_name'] = '[a-z,0-9]'; + $CodeTypes[7]['code_name'] = '[A-Z,a-z,0-9]'; + $CodeTypes[8]['code_name'] = '[A-Z,a-z,0-9,-_]'; + + $CodeTypes[1]['code_style'] = 'Alphabetical -> Simple:Capital letters'; + $CodeTypes[2]['code_style'] = 'Alphabetical -> Simple:Small letters'; + $CodeTypes[3]['code_style'] = 'Alphabetical -> Combi:Capital and small letters'; + $CodeTypes[4]['code_style'] = 'Numerical -> Simple'; + $CodeTypes[5]['code_style'] = 'Alphabetical and Numerical -> Simple:Capital letters(Megaupload.com)'; + $CodeTypes[6]['code_style'] = 'Alphabetical and Numerical -> Simple:Small letters'; + $CodeTypes[7]['code_style'] = 'Alphabetical and Numerical -> Combi:Capital and small letters'; + $CodeTypes[8]['code_style'] = 'Alphabetical and Numerical -> Combi:Capital and small letters plus special chars(Youtube.com)'; + + $CodeTypes[1]['code_generated_time'] = microtime(TRUE); + $CodeTypes[2]['code_generated_time'] = microtime(TRUE); + $CodeTypes[3]['code_generated_time'] = microtime(TRUE); + $CodeTypes[4]['code_generated_time'] = microtime(TRUE); + $CodeTypes[5]['code_generated_time'] = microtime(TRUE); + $CodeTypes[6]['code_generated_time'] = microtime(TRUE); + $CodeTypes[7]['code_generated_time'] = microtime(TRUE); + $CodeTypes[8]['code_generated_time'] = microtime(TRUE); + + $CodeTypes[1]['code_char_range'] = range('A','Z'); + $CodeTypes[2]['code_char_range'] = range('a','z'); + $CodeTypes[3]['code_char_range'] = array_merge(range('A','Z'), range('a','z')); + $CodeTypes[4]['code_char_range'] = range('0','9'); + $CodeTypes[5]['code_char_range'] = array_merge(range('A','Z'), range('0','9')); + $CodeTypes[6]['code_char_range'] = array_merge(range('a','z'), range('0','9')); + $CodeTypes[7]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9')); + $CodeTypes[8]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9'),array('-','_')); + + $CodeTypes[1]['code_char_count'] = count($CodeTypes[1]['code_char_range']); + $CodeTypes[2]['code_char_count'] = count($CodeTypes[2]['code_char_range']); + $CodeTypes[3]['code_char_count'] = count($CodeTypes[3]['code_char_range']); + $CodeTypes[4]['code_char_count'] = count($CodeTypes[4]['code_char_range']); + $CodeTypes[5]['code_char_count'] = count($CodeTypes[5]['code_char_range']); + $CodeTypes[6]['code_char_count'] = count($CodeTypes[6]['code_char_range']); + $CodeTypes[7]['code_char_count'] = count($CodeTypes[7]['code_char_range']); + $CodeTypes[8]['code_char_count'] = count($CodeTypes[8]['code_char_range']); + + $CodeTypes[1]['code_max_number'] = $this->CodeCountRange($CodeTypes[1]['code_char_range']); + $CodeTypes[2]['code_max_number'] = $this->CodeCountRange($CodeTypes[2]['code_char_range']); + $CodeTypes[3]['code_max_number'] = $this->CodeCountRange($CodeTypes[3]['code_char_range']); + $CodeTypes[4]['code_max_number'] = $this->CodeCountRange($CodeTypes[4]['code_char_range']); + $CodeTypes[5]['code_max_number'] = $this->CodeCountRange($CodeTypes[5]['code_char_range']); + $CodeTypes[6]['code_max_number'] = $this->CodeCountRange($CodeTypes[6]['code_char_range']); + $CodeTypes[7]['code_max_number'] = $this->CodeCountRange($CodeTypes[7]['code_char_range']); + $CodeTypes[8]['code_max_number'] = $this->CodeCountRange($CodeTypes[8]['code_char_range']); + + $this->CodeType = $CodeTypes[$this->default_code_type]; + } + + public function CodeInput($CodeInput=''){ + if(!empty($CodeInput)){ + $this->run_default_code = FALSE; + $this->CodeInputOld = $CodeInput; + }else{ + $this->run_random_code = FALSE; + } + } + + public function CodeCreateNext(){ + $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; + $code_char_range_start = reset($code_char_range); + $code_char_range_end = end($code_char_range); + + $chars = $this->CodeType['code_char_range']; + + $code_array = str_split($this->CodeInputOld); + + // Starts a search for the next incrementable character, ie, other than Z + // Note that it starts from the last character for the first character + for($i = count($code_array)-1;$i>-1;$i--){ + if($code_array[$i] == $code_char_range_end){ + if($i==0){ + // If it is equal to Z and is the first character, then it increases the length and zera + $code_array = array_fill(0,count($code_array) + 1,0); + return $code_array; + }else{ + if($code_array[$i -1] != $code_char_range_end){ + // If the previous character is different from Z, it increments it and clears the current and subsequent characters + // If the previous character is the first one, it also works, because it increments it and zeroes the others + $code_array[$i -1] = $chars[array_search($code_array[$i -1],$chars) + 1]; + for($j = $i; $j < count($code_array); $j++){ + $code_array[$j] = 0; + } + return $code_array; + } + } + }else{ + // calculates the next character, ie, increments the current character + $code_array[$i] = $chars[array_search($code_array[$i],$chars) + 1]; + if($i == 0){ + // If it is the first character, it means that the others are z + // That is, he zeroes them + $novo_array = array_fill(0,count($code_array),0); + $novo_array[0] = $code_array[$i]; + $code_array = $novo_array; + } + return $code_array; + } + } + } + + public function CodeCreate(){ + + $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; + $code_char_range_start = reset($code_char_range); + $code_char_range_end = end($code_char_range); + + $this->code_char_base = []; + if($this->run_default_code){ + for($n=1;$this->default_code_length>=$n;$n++){ + if($this->run_random_code){ + $this->code_char_base[] = $code_char_range[rand(0,($code_char_count-1))]; + }else{ + $this->code_char_base[] = $code_char_range_start; + } + } + }else{ + $this->code_char_base = $this->CodeCreateNext(); + } + } + + public function CodeCountNumber() { + $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; + + $character_keys = array_flip($code_char_range); + $code_characters = $this->code_char_base; + + $number = 0; + for ($i = 0; $i < count($code_characters); $i++) { + $number = $number * $code_char_count + $character_keys[$code_characters[$i]]; + } + $this->code_pos_num = ($number+1); + } + + public function Generate(){ + $this->CodeTypes(); + $this->CodeCreate(); + $this->CodeCountNumber(); + $code_base = implode($this->code_char_base); + return array( + 'code_base'=>$code_base, + 'code_base_md5'=>md5($code_base), + 'code_base_sha1'=>sha1($code_base), + 'code_base64_encode'=>base64_encode($code_base), + 'code_max_number'=>$this->CodeType['code_max_number'], + 'code_pos_num'=>$this->code_pos_num, + 'code_time'=>$this->CodeType['code_generated_time'], + 'code_message'=>'', + 'code_name'=>$this->CodeType['code_name'], + 'code_type'=>$this->default_code_type, + 'code_max_type'=>$this->code_max_type, + 'code_length'=>$this->default_code_length + ); + } +} +?> From 481bab2cdef61b341bb1e66d16f8403e4a35eb0c Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Mon, 13 Mar 2017 03:52:01 +0000 Subject: [PATCH 05/72] Create Example.php --- v.0.3/Example.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 v.0.3/Example.php diff --git a/v.0.3/Example.php b/v.0.3/Example.php new file mode 100644 index 0000000..cb87808 --- /dev/null +++ b/v.0.3/Example.php @@ -0,0 +1,14 @@ +SetLength(8); +$UniqueKey->SetType(5); + +$UniqueKey->CodeInput(); +$return = $UniqueKey->Generate(); +print_r($return); + +$UniqueKey->CodeInput($return['code_base']); +$return = $UniqueKey->Generate(); +print_r($return); +?> From d2a210de8a428481df9518217cf83414194b5e1a Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Mon, 13 Mar 2017 23:16:27 +0000 Subject: [PATCH 06/72] Create unique_key_generator.php --- v.0.2/unique_key_generator.php | 148 +++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 v.0.2/unique_key_generator.php diff --git a/v.0.2/unique_key_generator.php b/v.0.2/unique_key_generator.php new file mode 100644 index 0000000..ab9e339 --- /dev/null +++ b/v.0.2/unique_key_generator.php @@ -0,0 +1,148 @@ + Time stamp +$code_time = time(); +//Informace o tom kolik druhu klicu muze funkce poskytnout +$code_max_type = 5; +//Druhy klicu +if ($default_code_type==1){ +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('a','z')); +//Jmeno generovaneho klice +$code_name = '[A-Z,a-z]'; +//Cislo generovaneho klice +$code_number = 1; +} +if ($default_code_type==2){ +//Megaupload.com style +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('0','9')); +//Jmeno generovaneho klice +$code_name = '[A-Z,0-9]'; +//Cislo generovaneho klice +$code_number = 2; +} +if ($default_code_type==3){ +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('a','z'), range('0','9')); +//Jmeno generovaneho klice +$code_name = '[a-z,0-9]'; +//Cislo generovaneho klice +$code_number = 3; +} +if ($default_code_type==4){ +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('a','z'), range('0','9')); +//Jmeno generovaneho klice +$code_name = '[A-Z,a-z,0-9]'; +//Cislo generovaneho klice +$code_number = 4; +} +if ($default_code_type>4){ +//Youtube.com style +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('a','z'), range('0','9'),array('-','_')); +//Jmeno generovaneho klice +$code_name = '[A-Z,a-z,0-9,-_]'; +//Cislo generovaneho klice +$code_number = 5; +} +//Vypocet kolik klicu muze generator poskytnout +$count_characters = count($characters); +$count_range = pow($count_characters, $default_code_length); +//Oznaceni konce ve vypoctu klicu +$character_end = 'Z'; +$character_start = ''; +$array_chars = array_flip($characters); +//Podminka slouzi pro detekci jestly ma funkce vygenerovat pocatecni ,nahodny nebo nasledujici klic + if ($default_code==false){ +//Generator nahodneho nebo pocatecniho klice +for ($n=1;$default_code_length>=$n;$n++){ +if ($code_random){ +//Generace nahodneho klice +$character_start .= $characters[rand(0,($count_characters-1))]; +}else{ +//Generace pocatecniho klice +$character_start .= 'A'; +} +} +$code_base = $character_start; + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_time'=>$code_time,'code_count'=>code_count($code_base,$array_chars),'code_range'=>$count_range,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +}else{ +//Generace nasledujiciho klice + $chars = $characters; + $code_array = str_split($default_code); + // Starts searching for the next character capable of increasing, or different from Z + // Note that initiates the last character to the first + for($i = count($code_array)-1;$i>-1;$i--){ + if($code_array[$i] == $character_end){ + if($i=='0'){ + //If equal to Z and is the first character, mental increases the length and zeroes + $code_array = array_fill(0,count($code_array) + 1,0); +$code_base = implode("",$code_array); +//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu +if ($default_code_length==strlen($code_base)){ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }else{ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +} + }else{ + if($code_array[$i -1] != $character_end){ + // If the character is different from previous Z, increment it and resets the current and subsequent + // If the character is above the first, also works because it increases and the other resets + $code_array[$i -1] = $chars[array_search($code_array[$i -1],$chars) + 1]; + for($j = $i; $j < count($code_array); $j++){ + $code_array[$j] = '0'; + } +$code_base = implode("",$code_array); +//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu +if ($default_code_length==strlen($code_base)){ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }else{ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +} + } + } + + }else{ + // calculate the next character, or increments the current + $code_array[$i] = $chars[array_search($code_array[$i],$chars) + 1]; + if($i == '0'){ + // If the first character, meaning others Salo z + // That is, they reset + $novo_array = array_fill(0,count($code_array),0); + $novo_array[0] = $code_array[$i]; + $code_array = $novo_array; + } +$code_base = implode("",$code_array); +//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu +if ($default_code_length==strlen($code_base)){ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }else{ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +} + } + } +} + +} +?> From 2a26507312425a544932e5bc3d1ba1eb3c7272af Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Tue, 14 Mar 2017 23:19:12 +0000 Subject: [PATCH 07/72] Update Example.php --- v.0.3/Example.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/v.0.3/Example.php b/v.0.3/Example.php index cb87808..7b8c97f 100644 --- a/v.0.3/Example.php +++ b/v.0.3/Example.php @@ -5,10 +5,10 @@ $UniqueKey->SetType(5); $UniqueKey->CodeInput(); -$return = $UniqueKey->Generate(); +$return = $UniqueKey->Generate_String(); print_r($return); $UniqueKey->CodeInput($return['code_base']); -$return = $UniqueKey->Generate(); +$return = $UniqueKey->Generate_String(); print_r($return); ?> From 41a10c127ce3344e896d38e8fce4107b0033aed8 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Tue, 14 Mar 2017 23:21:07 +0000 Subject: [PATCH 08/72] Update UniqueKey.php --- v.0.3/UniqueKey.php | 62 +++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/v.0.3/UniqueKey.php b/v.0.3/UniqueKey.php index e6f6311..375d379 100644 --- a/v.0.3/UniqueKey.php +++ b/v.0.3/UniqueKey.php @@ -8,7 +8,7 @@ class UniqueKey { protected $code_max_type = 8; public function __construct(){ - + set_time_limit(0); } public function SetLength($SetLength=FALSE){ @@ -18,7 +18,7 @@ public function SetLength($SetLength=FALSE){ } public function SetType($SetType=FALSE){ - if(is_numeric($SetType) AND $SetType>=2 AND $this->code_max_type>=$SetType){ + if(is_numeric($SetType) AND $this->code_max_type>=$SetType){ $this->default_code_type = $SetType; } } @@ -85,6 +85,7 @@ public function CodeTypes(){ $CodeTypes[8]['code_max_number'] = $this->CodeCountRange($CodeTypes[8]['code_char_range']); $this->CodeType = $CodeTypes[$this->default_code_type]; + return $CodeTypes; } public function CodeInput($CodeInput=''){ @@ -102,40 +103,38 @@ public function CodeCreateNext(){ $code_char_range_start = reset($code_char_range); $code_char_range_end = end($code_char_range); - $chars = $this->CodeType['code_char_range']; - - $code_array = str_split($this->CodeInputOld); + $code_str_split = str_split($this->CodeInputOld); - // Starts a search for the next incrementable character, ie, other than Z + // Starts a search for the next incrementable character, ie, other than code_char_range_end // Note that it starts from the last character for the first character - for($i = count($code_array)-1;$i>-1;$i--){ - if($code_array[$i] == $code_char_range_end){ + for($i = count($code_str_split)-1;$i>-1;$i--){ + if($code_str_split[$i] == $code_char_range_end){ if($i==0){ - // If it is equal to Z and is the first character, then it increases the length and zera - $code_array = array_fill(0,count($code_array) + 1,0); - return $code_array; + // If it is equal to code_char_range_end and is the first character, then it increases the length and zera + $code_str_split = array_fill(0,count($code_str_split) + 1,0); + return $code_str_split; }else{ - if($code_array[$i -1] != $code_char_range_end){ - // If the previous character is different from Z, it increments it and clears the current and subsequent characters + if($code_str_split[$i -1] != $code_char_range_end){ + // If the previous character is different from code_char_range_end, it increments it and clears the current and subsequent characters // If the previous character is the first one, it also works, because it increments it and zeroes the others - $code_array[$i -1] = $chars[array_search($code_array[$i -1],$chars) + 1]; - for($j = $i; $j < count($code_array); $j++){ - $code_array[$j] = 0; + $code_str_split[$i -1] = $code_char_range[array_search($code_str_split[$i -1],$code_char_range) + 1]; + for($j = $i; $j < count($code_str_split); $j++){ + $code_str_split[$j] = $code_char_range_start; } - return $code_array; + return $code_str_split; } } }else{ // calculates the next character, ie, increments the current character - $code_array[$i] = $chars[array_search($code_array[$i],$chars) + 1]; + $code_str_split[$i] = $code_char_range[array_search($code_str_split[$i],$code_char_range) + 1]; if($i == 0){ - // If it is the first character, it means that the others are z + // If it is the first character, it means that the others are code_char_range_end // That is, he zeroes them - $novo_array = array_fill(0,count($code_array),0); - $novo_array[0] = $code_array[$i]; - $code_array = $novo_array; + $novo_array = array_fill(0,count($code_str_split),0); + $novo_array[0] = $code_str_split[$i]; + $code_str_split = $novo_array; } - return $code_array; + return $code_str_split; } } } @@ -175,7 +174,7 @@ public function CodeCountNumber() { $this->code_pos_num = ($number+1); } - public function Generate(){ + public function Generate_String(){ $this->CodeTypes(); $this->CodeCreate(); $this->CodeCountNumber(); @@ -195,5 +194,20 @@ public function Generate(){ 'code_length'=>$this->default_code_length ); } + + public function Generate_ID($GenerateID){ + is_numeric($GenerateID) OR die('The ID must be numberic!'); + for($i=1;$i<=$GenerateID;$i++){ + if($i==1){ + $this->CodeInput(); + }else{ + $this->CodeInput($CodeArray['code_base']); + } + $CodeArray = $this->Generate_String(); + if($CodeArray['code_pos_num']==$GenerateID){ + return $CodeArray; + } + } + } } ?> From 29c8b468b2361ca89258909d4e9b6fb9c741fd19 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Tue, 14 Mar 2017 23:26:51 +0000 Subject: [PATCH 09/72] Create Example_Generate_ID.php --- v.0.3/Example_Generate_ID.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 v.0.3/Example_Generate_ID.php diff --git a/v.0.3/Example_Generate_ID.php b/v.0.3/Example_Generate_ID.php new file mode 100644 index 0000000..fd82016 --- /dev/null +++ b/v.0.3/Example_Generate_ID.php @@ -0,0 +1,8 @@ +SetLength(8); +$UniqueKey->SetType(5); +$return = $UniqueKey->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> From f2ce355647fa5260ea8af25145268b5dbf3151b7 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 15 Mar 2017 01:32:33 +0000 Subject: [PATCH 10/72] Update UniqueKey.php --- v.0.3/UniqueKey.php | 159 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/v.0.3/UniqueKey.php b/v.0.3/UniqueKey.php index 375d379..a4d02ab 100644 --- a/v.0.3/UniqueKey.php +++ b/v.0.3/UniqueKey.php @@ -195,6 +195,165 @@ public function Generate_String(){ ); } + public function Generate_ID($GenerateID){ + is_numeric($GenerateID) OR die('The ID must be numberic!'); + for($i=1;$i<=$GenerateID;$i++){ + if($i==1){ + $this->CodeInput(); + }else{ + $this->CodeInput($CodeArray['code_base']); + } + $CodeArray = $this->Generate_String(); + if($GenerateID>$CodeArray['code_max_number']){ + $Minus_How_Much = ($GenerateID-$CodeArray['code_max_number']); + $CorrectID = ($GenerateID-$Minus_How_Much); + if($CodeArray['code_pos_num']==$CorrectID){ + return $CodeArray; + break; + } + }else{ + if($CodeArray['code_pos_num']==$GenerateID){ + return $CodeArray; + } + } + } + } +} +?> + $CodeTypes[5]['code_char_range'] = array_merge(range('A','Z'), range('0','9')); + $CodeTypes[6]['code_char_range'] = array_merge(range('a','z'), range('0','9')); + $CodeTypes[7]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9')); + $CodeTypes[8]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9'),array('-','_')); + + $CodeTypes[1]['code_char_count'] = count($CodeTypes[1]['code_char_range']); + $CodeTypes[2]['code_char_count'] = count($CodeTypes[2]['code_char_range']); + $CodeTypes[3]['code_char_count'] = count($CodeTypes[3]['code_char_range']); + $CodeTypes[4]['code_char_count'] = count($CodeTypes[4]['code_char_range']); + $CodeTypes[5]['code_char_count'] = count($CodeTypes[5]['code_char_range']); + $CodeTypes[6]['code_char_count'] = count($CodeTypes[6]['code_char_range']); + $CodeTypes[7]['code_char_count'] = count($CodeTypes[7]['code_char_range']); + $CodeTypes[8]['code_char_count'] = count($CodeTypes[8]['code_char_range']); + + $CodeTypes[1]['code_max_number'] = $this->CodeCountRange($CodeTypes[1]['code_char_range']); + $CodeTypes[2]['code_max_number'] = $this->CodeCountRange($CodeTypes[2]['code_char_range']); + $CodeTypes[3]['code_max_number'] = $this->CodeCountRange($CodeTypes[3]['code_char_range']); + $CodeTypes[4]['code_max_number'] = $this->CodeCountRange($CodeTypes[4]['code_char_range']); + $CodeTypes[5]['code_max_number'] = $this->CodeCountRange($CodeTypes[5]['code_char_range']); + $CodeTypes[6]['code_max_number'] = $this->CodeCountRange($CodeTypes[6]['code_char_range']); + $CodeTypes[7]['code_max_number'] = $this->CodeCountRange($CodeTypes[7]['code_char_range']); + $CodeTypes[8]['code_max_number'] = $this->CodeCountRange($CodeTypes[8]['code_char_range']); + + $this->CodeType = $CodeTypes[$this->default_code_type]; + return $CodeTypes; + } + + public function CodeInput($CodeInput=''){ + if(!empty($CodeInput)){ + $this->run_default_code = FALSE; + $this->CodeInputOld = $CodeInput; + }else{ + $this->run_random_code = FALSE; + } + } + + public function CodeCreateNext(){ + $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; + $code_char_range_start = reset($code_char_range); + $code_char_range_end = end($code_char_range); + + $code_str_split = str_split($this->CodeInputOld); + + // Starts a search for the next incrementable character, ie, other than code_char_range_end + // Note that it starts from the last character for the first character + for($i = count($code_str_split)-1;$i>-1;$i--){ + if($code_str_split[$i] == $code_char_range_end){ + if($i==0){ + // If it is equal to code_char_range_end and is the first character, then it increases the length and zera + $code_str_split = array_fill(0,count($code_str_split) + 1,0); + return $code_str_split; + }else{ + if($code_str_split[$i -1] != $code_char_range_end){ + // If the previous character is different from code_char_range_end, it increments it and clears the current and subsequent characters + // If the previous character is the first one, it also works, because it increments it and zeroes the others + $code_str_split[$i -1] = $code_char_range[array_search($code_str_split[$i -1],$code_char_range) + 1]; + for($j = $i; $j < count($code_str_split); $j++){ + $code_str_split[$j] = $code_char_range_start; + } + return $code_str_split; + } + } + }else{ + // calculates the next character, ie, increments the current character + $code_str_split[$i] = $code_char_range[array_search($code_str_split[$i],$code_char_range) + 1]; + if($i == 0){ + // If it is the first character, it means that the others are code_char_range_end + // That is, he zeroes them + $novo_array = array_fill(0,count($code_str_split),0); + $novo_array[0] = $code_str_split[$i]; + $code_str_split = $novo_array; + } + return $code_str_split; + } + } + } + + public function CodeCreate(){ + + $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; + $code_char_range_start = reset($code_char_range); + $code_char_range_end = end($code_char_range); + + $this->code_char_base = []; + if($this->run_default_code){ + for($n=1;$this->default_code_length>=$n;$n++){ + if($this->run_random_code){ + $this->code_char_base[] = $code_char_range[rand(0,($code_char_count-1))]; + }else{ + $this->code_char_base[] = $code_char_range_start; + } + } + }else{ + $this->code_char_base = $this->CodeCreateNext(); + } + } + + public function CodeCountNumber() { + $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; + + $character_keys = array_flip($code_char_range); + $code_characters = $this->code_char_base; + + $number = 0; + for ($i = 0; $i < count($code_characters); $i++) { + $number = $number * $code_char_count + $character_keys[$code_characters[$i]]; + } + $this->code_pos_num = ($number+1); + } + + public function Generate_String(){ + $this->CodeTypes(); + $this->CodeCreate(); + $this->CodeCountNumber(); + $code_base = implode($this->code_char_base); + return array( + 'code_base'=>$code_base, + 'code_base_md5'=>md5($code_base), + 'code_base_sha1'=>sha1($code_base), + 'code_base64_encode'=>base64_encode($code_base), + 'code_max_number'=>$this->CodeType['code_max_number'], + 'code_pos_num'=>$this->code_pos_num, + 'code_time'=>$this->CodeType['code_generated_time'], + 'code_message'=>'', + 'code_name'=>$this->CodeType['code_name'], + 'code_type'=>$this->default_code_type, + 'code_max_type'=>$this->code_max_type, + 'code_length'=>$this->default_code_length + ); + } + public function Generate_ID($GenerateID){ is_numeric($GenerateID) OR die('The ID must be numberic!'); for($i=1;$i<=$GenerateID;$i++){ From 916c71085ea1490989dc7d4eb0f3f54ac5003e8e Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 15 Mar 2017 01:36:31 +0000 Subject: [PATCH 11/72] Update UniqueKey.php --- v.0.3/UniqueKey.php | 150 -------------------------------------------- 1 file changed, 150 deletions(-) diff --git a/v.0.3/UniqueKey.php b/v.0.3/UniqueKey.php index a4d02ab..6ee418e 100644 --- a/v.0.3/UniqueKey.php +++ b/v.0.3/UniqueKey.php @@ -219,154 +219,4 @@ public function Generate_ID($GenerateID){ } } } -?> - $CodeTypes[5]['code_char_range'] = array_merge(range('A','Z'), range('0','9')); - $CodeTypes[6]['code_char_range'] = array_merge(range('a','z'), range('0','9')); - $CodeTypes[7]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9')); - $CodeTypes[8]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9'),array('-','_')); - - $CodeTypes[1]['code_char_count'] = count($CodeTypes[1]['code_char_range']); - $CodeTypes[2]['code_char_count'] = count($CodeTypes[2]['code_char_range']); - $CodeTypes[3]['code_char_count'] = count($CodeTypes[3]['code_char_range']); - $CodeTypes[4]['code_char_count'] = count($CodeTypes[4]['code_char_range']); - $CodeTypes[5]['code_char_count'] = count($CodeTypes[5]['code_char_range']); - $CodeTypes[6]['code_char_count'] = count($CodeTypes[6]['code_char_range']); - $CodeTypes[7]['code_char_count'] = count($CodeTypes[7]['code_char_range']); - $CodeTypes[8]['code_char_count'] = count($CodeTypes[8]['code_char_range']); - - $CodeTypes[1]['code_max_number'] = $this->CodeCountRange($CodeTypes[1]['code_char_range']); - $CodeTypes[2]['code_max_number'] = $this->CodeCountRange($CodeTypes[2]['code_char_range']); - $CodeTypes[3]['code_max_number'] = $this->CodeCountRange($CodeTypes[3]['code_char_range']); - $CodeTypes[4]['code_max_number'] = $this->CodeCountRange($CodeTypes[4]['code_char_range']); - $CodeTypes[5]['code_max_number'] = $this->CodeCountRange($CodeTypes[5]['code_char_range']); - $CodeTypes[6]['code_max_number'] = $this->CodeCountRange($CodeTypes[6]['code_char_range']); - $CodeTypes[7]['code_max_number'] = $this->CodeCountRange($CodeTypes[7]['code_char_range']); - $CodeTypes[8]['code_max_number'] = $this->CodeCountRange($CodeTypes[8]['code_char_range']); - - $this->CodeType = $CodeTypes[$this->default_code_type]; - return $CodeTypes; - } - - public function CodeInput($CodeInput=''){ - if(!empty($CodeInput)){ - $this->run_default_code = FALSE; - $this->CodeInputOld = $CodeInput; - }else{ - $this->run_random_code = FALSE; - } - } - - public function CodeCreateNext(){ - $code_char_count = $this->CodeType['code_char_count']; - $code_char_range = $this->CodeType['code_char_range']; - $code_char_range_start = reset($code_char_range); - $code_char_range_end = end($code_char_range); - - $code_str_split = str_split($this->CodeInputOld); - - // Starts a search for the next incrementable character, ie, other than code_char_range_end - // Note that it starts from the last character for the first character - for($i = count($code_str_split)-1;$i>-1;$i--){ - if($code_str_split[$i] == $code_char_range_end){ - if($i==0){ - // If it is equal to code_char_range_end and is the first character, then it increases the length and zera - $code_str_split = array_fill(0,count($code_str_split) + 1,0); - return $code_str_split; - }else{ - if($code_str_split[$i -1] != $code_char_range_end){ - // If the previous character is different from code_char_range_end, it increments it and clears the current and subsequent characters - // If the previous character is the first one, it also works, because it increments it and zeroes the others - $code_str_split[$i -1] = $code_char_range[array_search($code_str_split[$i -1],$code_char_range) + 1]; - for($j = $i; $j < count($code_str_split); $j++){ - $code_str_split[$j] = $code_char_range_start; - } - return $code_str_split; - } - } - }else{ - // calculates the next character, ie, increments the current character - $code_str_split[$i] = $code_char_range[array_search($code_str_split[$i],$code_char_range) + 1]; - if($i == 0){ - // If it is the first character, it means that the others are code_char_range_end - // That is, he zeroes them - $novo_array = array_fill(0,count($code_str_split),0); - $novo_array[0] = $code_str_split[$i]; - $code_str_split = $novo_array; - } - return $code_str_split; - } - } - } - - public function CodeCreate(){ - - $code_char_count = $this->CodeType['code_char_count']; - $code_char_range = $this->CodeType['code_char_range']; - $code_char_range_start = reset($code_char_range); - $code_char_range_end = end($code_char_range); - - $this->code_char_base = []; - if($this->run_default_code){ - for($n=1;$this->default_code_length>=$n;$n++){ - if($this->run_random_code){ - $this->code_char_base[] = $code_char_range[rand(0,($code_char_count-1))]; - }else{ - $this->code_char_base[] = $code_char_range_start; - } - } - }else{ - $this->code_char_base = $this->CodeCreateNext(); - } - } - - public function CodeCountNumber() { - $code_char_count = $this->CodeType['code_char_count']; - $code_char_range = $this->CodeType['code_char_range']; - - $character_keys = array_flip($code_char_range); - $code_characters = $this->code_char_base; - - $number = 0; - for ($i = 0; $i < count($code_characters); $i++) { - $number = $number * $code_char_count + $character_keys[$code_characters[$i]]; - } - $this->code_pos_num = ($number+1); - } - - public function Generate_String(){ - $this->CodeTypes(); - $this->CodeCreate(); - $this->CodeCountNumber(); - $code_base = implode($this->code_char_base); - return array( - 'code_base'=>$code_base, - 'code_base_md5'=>md5($code_base), - 'code_base_sha1'=>sha1($code_base), - 'code_base64_encode'=>base64_encode($code_base), - 'code_max_number'=>$this->CodeType['code_max_number'], - 'code_pos_num'=>$this->code_pos_num, - 'code_time'=>$this->CodeType['code_generated_time'], - 'code_message'=>'', - 'code_name'=>$this->CodeType['code_name'], - 'code_type'=>$this->default_code_type, - 'code_max_type'=>$this->code_max_type, - 'code_length'=>$this->default_code_length - ); - } - - public function Generate_ID($GenerateID){ - is_numeric($GenerateID) OR die('The ID must be numberic!'); - for($i=1;$i<=$GenerateID;$i++){ - if($i==1){ - $this->CodeInput(); - }else{ - $this->CodeInput($CodeArray['code_base']); - } - $CodeArray = $this->Generate_String(); - if($CodeArray['code_pos_num']==$GenerateID){ - return $CodeArray; - } - } - } -} ?> From 75cc2274e44f660238817105d51051062ae36e03 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 15 Mar 2017 01:40:49 +0000 Subject: [PATCH 12/72] Rename readme.md to v.0.1/readme.md --- readme.md => v.0.1/readme.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename readme.md => v.0.1/readme.md (100%) diff --git a/readme.md b/v.0.1/readme.md similarity index 100% rename from readme.md rename to v.0.1/readme.md From 066209096848358274876a28112df5a7ee937d6b Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 15 Mar 2017 01:43:59 +0000 Subject: [PATCH 13/72] Delete .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7053dc1..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/coverage/ From ef773f4cf428323bc74c81c7f33092dc7c8c1ed1 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 18 Mar 2017 00:24:08 +0000 Subject: [PATCH 14/72] Final Update UniqueKey.php array_search() could not search in array properly and changed to own searching style. Because of this issue , generator could not generate by id correctly. --- v.0.3/UniqueKey.php | 49 +++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/v.0.3/UniqueKey.php b/v.0.3/UniqueKey.php index 6ee418e..7ae6aeb 100644 --- a/v.0.3/UniqueKey.php +++ b/v.0.3/UniqueKey.php @@ -60,11 +60,11 @@ public function CodeTypes(){ $CodeTypes[1]['code_char_range'] = range('A','Z'); $CodeTypes[2]['code_char_range'] = range('a','z'); $CodeTypes[3]['code_char_range'] = array_merge(range('A','Z'), range('a','z')); - $CodeTypes[4]['code_char_range'] = range('0','9'); - $CodeTypes[5]['code_char_range'] = array_merge(range('A','Z'), range('0','9')); - $CodeTypes[6]['code_char_range'] = array_merge(range('a','z'), range('0','9')); - $CodeTypes[7]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9')); - $CodeTypes[8]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range('0','9'),array('-','_')); + $CodeTypes[4]['code_char_range'] = range(0,9); + $CodeTypes[5]['code_char_range'] = array_merge(range('A','Z'), range(0,9)); + $CodeTypes[6]['code_char_range'] = array_merge(range('a','z'), range(0,9)); + $CodeTypes[7]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range(0,9)); + $CodeTypes[8]['code_char_range'] = array_merge(range('A','Z'), range('a','z'), range(0,9),array('-','_')); $CodeTypes[1]['code_char_count'] = count($CodeTypes[1]['code_char_range']); $CodeTypes[2]['code_char_count'] = count($CodeTypes[2]['code_char_range']); @@ -97,6 +97,16 @@ public function CodeInput($CodeInput=''){ } } + public function Search($Value,$In_Array){ + foreach($In_Array AS $KeyNumber=>$KeyString){ + if("$KeyString"=="$Value"){ + return $KeyNumber; + break; + } + + } + } + public function CodeCreateNext(){ $code_char_count = $this->CodeType['code_char_count']; $code_char_range = $this->CodeType['code_char_range']; @@ -108,16 +118,18 @@ public function CodeCreateNext(){ // Starts a search for the next incrementable character, ie, other than code_char_range_end // Note that it starts from the last character for the first character for($i = count($code_str_split)-1;$i>-1;$i--){ - if($code_str_split[$i] == $code_char_range_end){ + if("$code_str_split[$i]" == "$code_char_range_end"){ if($i==0){ // If it is equal to code_char_range_end and is the first character, then it increases the length and zera - $code_str_split = array_fill(0,count($code_str_split) + 1,0); + $code_str_split = array_fill(0,count($code_str_split) + 1,$code_char_range_start); return $code_str_split; }else{ - if($code_str_split[$i -1] != $code_char_range_end){ + $n = $i-1; + $code_str_pos = $this->Search("$code_str_split[$n]",$code_char_range); + if("$code_str_split[$n]" != "$code_char_range_end"){ // If the previous character is different from code_char_range_end, it increments it and clears the current and subsequent characters // If the previous character is the first one, it also works, because it increments it and zeroes the others - $code_str_split[$i -1] = $code_char_range[array_search($code_str_split[$i -1],$code_char_range) + 1]; + $code_str_split[$n] = $code_char_range[$code_str_pos + 1]; for($j = $i; $j < count($code_str_split); $j++){ $code_str_split[$j] = $code_char_range_start; } @@ -125,12 +137,13 @@ public function CodeCreateNext(){ } } }else{ + $code_str_pos = $this->Search("$code_str_split[$i]",$code_char_range); // calculates the next character, ie, increments the current character - $code_str_split[$i] = $code_char_range[array_search($code_str_split[$i],$code_char_range) + 1]; + $code_str_split[$i] = $code_char_range[$code_str_pos + 1]; if($i == 0){ // If it is the first character, it means that the others are code_char_range_end // That is, he zeroes them - $novo_array = array_fill(0,count($code_str_split),0); + $novo_array = array_fill(0,count($code_str_split),$code_char_range_start); $novo_array[0] = $code_str_split[$i]; $code_str_split = $novo_array; } @@ -145,12 +158,12 @@ public function CodeCreate(){ $code_char_range = $this->CodeType['code_char_range']; $code_char_range_start = reset($code_char_range); $code_char_range_end = end($code_char_range); - + //print_r($code_char_range); $this->code_char_base = []; if($this->run_default_code){ for($n=1;$this->default_code_length>=$n;$n++){ if($this->run_random_code){ - $this->code_char_base[] = $code_char_range[rand(0,($code_char_count-1))]; + $this->code_char_base[] = $code_char_range[mt_rand(0,($code_char_count-1))]; }else{ $this->code_char_base[] = $code_char_range_start; } @@ -188,6 +201,7 @@ public function Generate_String(){ 'code_pos_num'=>$this->code_pos_num, 'code_time'=>$this->CodeType['code_generated_time'], 'code_message'=>'', + 'code_style'=>$this->CodeType['code_style'], 'code_name'=>$this->CodeType['code_name'], 'code_type'=>$this->default_code_type, 'code_max_type'=>$this->code_max_type, @@ -197,13 +211,10 @@ public function Generate_String(){ public function Generate_ID($GenerateID){ is_numeric($GenerateID) OR die('The ID must be numberic!'); + $this->CodeInput(); for($i=1;$i<=$GenerateID;$i++){ - if($i==1){ - $this->CodeInput(); - }else{ - $this->CodeInput($CodeArray['code_base']); - } $CodeArray = $this->Generate_String(); + $this->CodeInput($CodeArray['code_base']); if($GenerateID>$CodeArray['code_max_number']){ $Minus_How_Much = ($GenerateID-$CodeArray['code_max_number']); $CorrectID = ($GenerateID-$Minus_How_Much); @@ -213,7 +224,7 @@ public function Generate_ID($GenerateID){ } }else{ if($CodeArray['code_pos_num']==$GenerateID){ - return $CodeArray; + return $CodeArray; } } } From 6801f21d3ce09c3c4a9b953984ec76b8ac117a8a Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 18 Mar 2017 01:42:58 +0000 Subject: [PATCH 15/72] Rename Example.php to Example_Generate_String.php --- v.0.3/{Example.php => Example_Generate_String.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename v.0.3/{Example.php => Example_Generate_String.php} (100%) diff --git a/v.0.3/Example.php b/v.0.3/Example_Generate_String.php similarity index 100% rename from v.0.3/Example.php rename to v.0.3/Example_Generate_String.php From bbbdf4714a08d3ec5de7b15a094f9ddbfb5fc7dc Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 18 Mar 2017 02:32:19 +0000 Subject: [PATCH 16/72] Clean Code UniqueKey.php Just clean up of debug code. --- v.0.3/UniqueKey.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/v.0.3/UniqueKey.php b/v.0.3/UniqueKey.php index 7ae6aeb..ee22f6d 100644 --- a/v.0.3/UniqueKey.php +++ b/v.0.3/UniqueKey.php @@ -108,7 +108,7 @@ public function Search($Value,$In_Array){ } public function CodeCreateNext(){ - $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; $code_char_range_start = reset($code_char_range); $code_char_range_end = end($code_char_range); @@ -157,8 +157,7 @@ public function CodeCreate(){ $code_char_count = $this->CodeType['code_char_count']; $code_char_range = $this->CodeType['code_char_range']; $code_char_range_start = reset($code_char_range); - $code_char_range_end = end($code_char_range); - //print_r($code_char_range); + $this->code_char_base = []; if($this->run_default_code){ for($n=1;$this->default_code_length>=$n;$n++){ From dfe0f85c27f13f0eb69e3aa252ebaa159e0d1f53 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sun, 19 Mar 2017 12:34:55 +0000 Subject: [PATCH 17/72] Fix Update CANG.php Fixed a little bug when value was 0 -> generator could not generate the next value after the 0 because it was returning as FALSE. --- v.0.3/{UniqueKey.php => CANG.php} | 70 +++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 12 deletions(-) rename v.0.3/{UniqueKey.php => CANG.php} (77%) diff --git a/v.0.3/UniqueKey.php b/v.0.3/CANG.php similarity index 77% rename from v.0.3/UniqueKey.php rename to v.0.3/CANG.php index ee22f6d..e8d02a2 100644 --- a/v.0.3/UniqueKey.php +++ b/v.0.3/CANG.php @@ -1,5 +1,5 @@ $KeyString){ + public function Search($Value){ + $code_char_range = $this->CodeType['code_char_range']; + foreach($code_char_range AS $KeyNumber=>$KeyString){ if("$KeyString"=="$Value"){ return $KeyNumber; break; @@ -121,15 +122,19 @@ public function CodeCreateNext(){ if("$code_str_split[$i]" == "$code_char_range_end"){ if($i==0){ // If it is equal to code_char_range_end and is the first character, then it increases the length and zera - $code_str_split = array_fill(0,count($code_str_split) + 1,$code_char_range_start); + $code_str_split = array_fill(0,count($code_str_split) + 1,"$code_char_range_start"); return $code_str_split; }else{ $n = $i-1; - $code_str_pos = $this->Search("$code_str_split[$n]",$code_char_range); + $code_str_pos = $this->Search("$code_str_split[$n]")+1; if("$code_str_split[$n]" != "$code_char_range_end"){ // If the previous character is different from code_char_range_end, it increments it and clears the current and subsequent characters // If the previous character is the first one, it also works, because it increments it and zeroes the others - $code_str_split[$n] = $code_char_range[$code_str_pos + 1]; + if(empty($code_char_range[$code_str_pos])){ + $code_str_split[$n] = settype($code_char_range[$code_str_pos],'string'); + }else{ + $code_str_split[$n] = $code_char_range[$code_str_pos]; + } for($j = $i; $j < count($code_str_split); $j++){ $code_str_split[$j] = $code_char_range_start; } @@ -137,13 +142,17 @@ public function CodeCreateNext(){ } } }else{ - $code_str_pos = $this->Search("$code_str_split[$i]",$code_char_range); - // calculates the next character, ie, increments the current character - $code_str_split[$i] = $code_char_range[$code_str_pos + 1]; + // calculates the next character, ie, increments the current character + $code_str_pos = $this->Search("$code_str_split[$i]")+1; + if(empty($code_char_range[$code_str_pos])){ + $code_str_split[$i] = settype($code_char_range[$code_str_pos],'string'); + }else{ + $code_str_split[$i] = $code_char_range[$code_str_pos]; + } if($i == 0){ // If it is the first character, it means that the others are code_char_range_end // That is, he zeroes them - $novo_array = array_fill(0,count($code_str_split),$code_char_range_start); + $novo_array = array_fill(0,count($code_str_split),"$code_char_range_start"); $novo_array[0] = $code_str_split[$i]; $code_str_split = $novo_array; } @@ -191,7 +200,9 @@ public function Generate_String(){ $this->CodeCreate(); $this->CodeCountNumber(); $code_base = implode($this->code_char_base); - return array( + + if ($this->default_code_length==strlen($code_base)){ + return array( 'code_base'=>$code_base, 'code_base_md5'=>md5($code_base), 'code_base_sha1'=>sha1($code_base), @@ -199,13 +210,48 @@ public function Generate_String(){ 'code_max_number'=>$this->CodeType['code_max_number'], 'code_pos_num'=>$this->code_pos_num, 'code_time'=>$this->CodeType['code_generated_time'], - 'code_message'=>'', + 'code_message'=>'is_acurrate', 'code_style'=>$this->CodeType['code_style'], 'code_name'=>$this->CodeType['code_name'], 'code_type'=>$this->default_code_type, 'code_max_type'=>$this->code_max_type, 'code_length'=>$this->default_code_length ); + }elseif($this->default_code_length$code_base, + 'code_base_md5'=>md5($code_base), + 'code_base_sha1'=>sha1($code_base), + 'code_base64_encode'=>base64_encode($code_base), + 'code_max_number'=>$this->CodeType['code_max_number'], + 'code_pos_num'=>$this->code_pos_num, + 'code_time'=>$this->CodeType['code_generated_time'], + 'code_message'=>'is_upper_or_full', + 'code_style'=>$this->CodeType['code_style'], + 'code_name'=>$this->CodeType['code_name'], + 'code_type'=>$this->default_code_type, + 'code_max_type'=>$this->code_max_type, + 'code_length'=>$this->default_code_length + ); + }else{ + return array( + 'code_base'=>$code_base, + 'code_base_md5'=>md5($code_base), + 'code_base_sha1'=>sha1($code_base), + 'code_base64_encode'=>base64_encode($code_base), + 'code_max_number'=>$this->CodeType['code_max_number'], + 'code_pos_num'=>$this->code_pos_num, + 'code_time'=>$this->CodeType['code_generated_time'], + 'code_message'=>'is_lower', + 'code_style'=>$this->CodeType['code_style'], + 'code_name'=>$this->CodeType['code_name'], + 'code_type'=>$this->default_code_type, + 'code_max_type'=>$this->code_max_type, + 'code_length'=>$this->default_code_length + ); + } + + } public function Generate_ID($GenerateID){ From bd2d14f999db742eae24201b8d43e39c3ed55592 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sun, 19 Mar 2017 12:36:37 +0000 Subject: [PATCH 18/72] Update Example_Generate_ID.php --- v.0.3/Example_Generate_ID.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/v.0.3/Example_Generate_ID.php b/v.0.3/Example_Generate_ID.php index fd82016..d182982 100644 --- a/v.0.3/Example_Generate_ID.php +++ b/v.0.3/Example_Generate_ID.php @@ -1,8 +1,8 @@ SetLength(8); -$UniqueKey->SetType(5); -$return = $UniqueKey->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID +include('CANG.php'); +$CANG = new CANG; +$CANG->SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID print_r($return); ?> From e284a801349c989fc734685af498c8890d7b0aaa Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sun, 19 Mar 2017 12:39:23 +0000 Subject: [PATCH 19/72] Update Example_Generate_String.php --- v.0.3/Example_Generate_String.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/v.0.3/Example_Generate_String.php b/v.0.3/Example_Generate_String.php index 7b8c97f..a8298f4 100644 --- a/v.0.3/Example_Generate_String.php +++ b/v.0.3/Example_Generate_String.php @@ -1,14 +1,13 @@ SetLength(8); -$UniqueKey->SetType(5); +include('CANG.php'); +$CANG = new CANG; +$CANG->SetLength(8); +$CANG->SetType(5); -$UniqueKey->CodeInput(); -$return = $UniqueKey->Generate_String(); -print_r($return); +$CANG->CodeInput(); +$return[1] = $CANG->Generate_String(); -$UniqueKey->CodeInput($return['code_base']); -$return = $UniqueKey->Generate_String(); +$CANG->CodeInput($return[1]['code_base']); +$return[] = $CANG->Generate_String(); print_r($return); ?> From 4315e0f6b93b37cca1ec572ba49ba327f1e6480b Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sun, 19 Mar 2017 21:52:14 +0000 Subject: [PATCH 20/72] Final Update CANG.php -> Please read the details For now it's the final update, but still need to figure it out how to generate key quickest way. There need to be some reverse way of doing this : 0000 0000 = Code Number 0 0000 0001 = Code Number 1 0000 0158 = Code Number (1 * 10^2) + (5 * 10^1) + (8 * 10^0) = 158 For Alphabets (A=0, B=1, C= 2, ... Z = 25, a = 26, ..., z = 51, 0 = 52, 1 = 53, 9 = 61: AAAA ABCD = Code Number (0 * 62^7) + (0 * 62^6) + (0 * 62^5) + (0 + 62^4) + (0 * 62^3) + (1 * 62^2) + (2 * 62^1) + (3 * 62^0) = 14780307 This is the current way : generate key -> count the possicion of the key Solution wanted : input ID -> generate key without too much cycling by PHP "for" cycle At the moment if i input ID 5,000,000 with proper setting the script hang up or the page will become unavailable. I haven't found any simple solution of how to reverse it,but i believe there must be somethnig to solve this issue. So if anyone know a solution please feel free to develop and commit. Thanks --- v.0.3/CANG.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/v.0.3/CANG.php b/v.0.3/CANG.php index e8d02a2..a2c6070 100644 --- a/v.0.3/CANG.php +++ b/v.0.3/CANG.php @@ -39,14 +39,14 @@ public function CodeTypes(){ $CodeTypes[7]['code_name'] = '[A-Z,a-z,0-9]'; $CodeTypes[8]['code_name'] = '[A-Z,a-z,0-9,-_]'; - $CodeTypes[1]['code_style'] = 'Alphabetical -> Simple:Capital letters'; - $CodeTypes[2]['code_style'] = 'Alphabetical -> Simple:Small letters'; - $CodeTypes[3]['code_style'] = 'Alphabetical -> Combi:Capital and small letters'; - $CodeTypes[4]['code_style'] = 'Numerical -> Simple'; - $CodeTypes[5]['code_style'] = 'Alphabetical and Numerical -> Simple:Capital letters(Megaupload.com)'; - $CodeTypes[6]['code_style'] = 'Alphabetical and Numerical -> Simple:Small letters'; - $CodeTypes[7]['code_style'] = 'Alphabetical and Numerical -> Combi:Capital and small letters'; - $CodeTypes[8]['code_style'] = 'Alphabetical and Numerical -> Combi:Capital and small letters plus special chars(Youtube.com)'; + $CodeTypes[1]['code_description'] = 'Alphabetical -> Simple:Capital letters'; + $CodeTypes[2]['code_description'] = 'Alphabetical -> Simple:Small letters'; + $CodeTypes[3]['code_description'] = 'Alphabetical -> Combi:Capital and small letters'; + $CodeTypes[4]['code_description'] = 'Numerical -> Simple'; + $CodeTypes[5]['code_description'] = 'Alphabetical and Numerical -> Simple:Capital letters(Megaupload.com)'; + $CodeTypes[6]['code_description'] = 'Alphabetical and Numerical -> Simple:Small letters'; + $CodeTypes[7]['code_description'] = 'Alphabetical and Numerical -> Combi:Capital and small letters'; + $CodeTypes[8]['code_description'] = 'Alphabetical and Numerical -> Combi:Capital and small letters plus special chars(Youtube.com)'; $CodeTypes[1]['code_generated_time'] = microtime(TRUE); $CodeTypes[2]['code_generated_time'] = microtime(TRUE); @@ -211,8 +211,8 @@ public function Generate_String(){ 'code_pos_num'=>$this->code_pos_num, 'code_time'=>$this->CodeType['code_generated_time'], 'code_message'=>'is_acurrate', - 'code_style'=>$this->CodeType['code_style'], 'code_name'=>$this->CodeType['code_name'], + 'code_description'=>$this->CodeType['code_description'], 'code_type'=>$this->default_code_type, 'code_max_type'=>$this->code_max_type, 'code_length'=>$this->default_code_length @@ -227,8 +227,8 @@ public function Generate_String(){ 'code_pos_num'=>$this->code_pos_num, 'code_time'=>$this->CodeType['code_generated_time'], 'code_message'=>'is_upper_or_full', - 'code_style'=>$this->CodeType['code_style'], 'code_name'=>$this->CodeType['code_name'], + 'code_description'=>$this->CodeType['code_description'], 'code_type'=>$this->default_code_type, 'code_max_type'=>$this->code_max_type, 'code_length'=>$this->default_code_length @@ -243,8 +243,8 @@ public function Generate_String(){ 'code_pos_num'=>$this->code_pos_num, 'code_time'=>$this->CodeType['code_generated_time'], 'code_message'=>'is_lower', - 'code_style'=>$this->CodeType['code_style'], 'code_name'=>$this->CodeType['code_name'], + 'code_description'=>$this->CodeType['code_description'], 'code_type'=>$this->default_code_type, 'code_max_type'=>$this->code_max_type, 'code_length'=>$this->default_code_length From f18b0f5b47fc5bafa92eac2ec84f3a8f5040185c Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sun, 19 Mar 2017 23:10:31 +0000 Subject: [PATCH 21/72] Create Example_Generate_Random.php --- v.0.3/Example_Generate_Random.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 v.0.3/Example_Generate_Random.php diff --git a/v.0.3/Example_Generate_Random.php b/v.0.3/Example_Generate_Random.php new file mode 100644 index 0000000..3d87956 --- /dev/null +++ b/v.0.3/Example_Generate_Random.php @@ -0,0 +1,8 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_String(); +print_r($return); +?> From 455638f39a73c258c97c5d473a053d0ad12795a7 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Mon, 27 Mar 2017 16:10:56 +0100 Subject: [PATCH 22/72] Finished CANG.php Generator is finished 27.3.2017 16:10. --- v.0.3/CANG.php | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/v.0.3/CANG.php b/v.0.3/CANG.php index a2c6070..c395c62 100644 --- a/v.0.3/CANG.php +++ b/v.0.3/CANG.php @@ -195,13 +195,9 @@ public function CodeCountNumber() { $this->code_pos_num = ($number+1); } - public function Generate_String(){ - $this->CodeTypes(); - $this->CodeCreate(); - $this->CodeCountNumber(); + public function CodeArray(){ $code_base = implode($this->code_char_base); - - if ($this->default_code_length==strlen($code_base)){ + if($this->default_code_length==strlen($code_base)){ return array( 'code_base'=>$code_base, 'code_base_md5'=>md5($code_base), @@ -250,29 +246,35 @@ public function Generate_String(){ 'code_length'=>$this->default_code_length ); } - - + } + + public function Generate_String(){ + $this->CodeTypes(); + $this->CodeCreate(); + $this->CodeCountNumber(); + return $this->CodeArray(); } public function Generate_ID($GenerateID){ is_numeric($GenerateID) OR die('The ID must be numberic!'); - $this->CodeInput(); - for($i=1;$i<=$GenerateID;$i++){ - $CodeArray = $this->Generate_String(); - $this->CodeInput($CodeArray['code_base']); - if($GenerateID>$CodeArray['code_max_number']){ - $Minus_How_Much = ($GenerateID-$CodeArray['code_max_number']); - $CorrectID = ($GenerateID-$Minus_How_Much); - if($CodeArray['code_pos_num']==$CorrectID){ - return $CodeArray; - break; - } - }else{ - if($CodeArray['code_pos_num']==$GenerateID){ - return $CodeArray; - } - } + $this->CodeTypes(); + $code_char_count = $this->CodeType['code_char_count']; + $code_char_range = $this->CodeType['code_char_range']; + + $one = 1; + if($GenerateID>$this->CodeType['code_max_number']){ + $code_id = $this->CodeType['code_max_number'] - $one; + }else{ + $code_id = ($GenerateID - $one); } + for($length=($this->default_code_length - $one);$length>=0;$length--){ + $bcpow = bcpow($code_char_count, $length); + $possition = floor($code_id / $bcpow); + $code_id = $code_id - ($possition * $bcpow); + $this->code_char_base[] = $code_char_range[$possition]; + } + $this->CodeCountNumber(); + return $this->CodeArray(); } } ?> From 24f0c202c1b7b9ab791e8e8dbbd8edc6a8bfb36b Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 10 May 2017 21:10:43 +0100 Subject: [PATCH 23/72] Update CANG.php Repaired 1 bug. There was one error in generating code by ID. When generated two or more numbers at the same time '$this->code_char_base[]' was joining all generated code as one,so database couldn't recocnise correct code. --- v.0.3/CANG.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/v.0.3/CANG.php b/v.0.3/CANG.php index c395c62..eb37b55 100644 --- a/v.0.3/CANG.php +++ b/v.0.3/CANG.php @@ -263,7 +263,8 @@ public function Generate_ID($GenerateID){ $one = 1; if($GenerateID>$this->CodeType['code_max_number']){ - $code_id = $this->CodeType['code_max_number'] - $one; + //Perform reset + $code_id = ($one - $one); }else{ $code_id = ($GenerateID - $one); } @@ -271,7 +272,7 @@ public function Generate_ID($GenerateID){ $bcpow = bcpow($code_char_count, $length); $possition = floor($code_id / $bcpow); $code_id = $code_id - ($possition * $bcpow); - $this->code_char_base[] = $code_char_range[$possition]; + $this->code_char_base[$length] = $code_char_range[$possition]; } $this->CodeCountNumber(); return $this->CodeArray(); From 90a187b3e8eeb9b22eee5941f433660f5f57c2f3 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sun, 12 Nov 2017 14:39:57 +0000 Subject: [PATCH 24/72] Create README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..53579f1 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Complex_Alpha-Numeric_Generator +Complex Alphabetic or Numeric and AlphaNumeric Generator (CANG) : Generate key string Randomly or Sequentially by the ID or the string. +I have combined two working scripts to make this nice CANG.
+from :
+https://github.com/admiyn/sequential-alphanumeric-generator/blob/master/alphanumeric-generator.php
+and
+https://github.com/loader/kvzlib/blob/master/php/functions/alphaID.inc.php
+Just want to say a thanks to these two guys that they make me understand how to generate a key string for my generator. +And ofcourse a one thanks belonging to users which were helping me to understand at this czech website :
+https://diskuse.jakpsatweb.cz/?action=vthread&forum=9&topic=159759#12 From 704f64b6fa7ab26773fb7bc061c4be6ad6a9a971 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:01:10 +0000 Subject: [PATCH 25/72] Create Example_Generate_Random_Microsoft_SN.php --- v.0.3/Example_Generate_Random_Microsoft_SN.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 v.0.3/Example_Generate_Random_Microsoft_SN.php diff --git a/v.0.3/Example_Generate_Random_Microsoft_SN.php b/v.0.3/Example_Generate_Random_Microsoft_SN.php new file mode 100644 index 0000000..009b12c --- /dev/null +++ b/v.0.3/Example_Generate_Random_Microsoft_SN.php @@ -0,0 +1,8 @@ +SetLength(25); +$CANG->SetType(5); +$return = $CANG->Generate_String(); +echo implode('-',str_split($return['code_base'], 5)); +?> From f0c1f4038dfe08727bb26d8be917e4a1dc714426 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:09:30 +0000 Subject: [PATCH 26/72] Add files via upload --- ...key-coa-windows-5922174a3df78cf5facd7f7c.png | Bin 0 -> 44909 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 v.0.3/product-key-coa-windows-5922174a3df78cf5facd7f7c.png diff --git a/v.0.3/product-key-coa-windows-5922174a3df78cf5facd7f7c.png b/v.0.3/product-key-coa-windows-5922174a3df78cf5facd7f7c.png new file mode 100644 index 0000000000000000000000000000000000000000..557238e8bd042509faf01655d3d2fb49cfd80e42 GIT binary patch literal 44909 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

$6o=RUMe^`}yqPLI-(almW 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%0D3@bw7Gf0YS72pTZ-aQiO0XN6v3Z90szD| zpUIR)y%VGf!y>pKrgc4-4irui4uX*qcL_i zMU7daD$nT#g7%8dcN9Q)OZp_F3p(DDPSa9p?5j-OC(6RYWb)EDg8F09ufxCJ>>%v= z>$m&+d(8iX`M>l7h}FZxgTb4YF!~L>2LO1%u)yI-umon$0I+4y{S^T4o3lro8`=sv z*3CQYj34(0r6Wzhd+a|-MN`95vT=Xfoh`j&F`-4$6Uy7uYQF`0~s8OJs4 zc|w|T&-9+D4j4+q+)_=v9u?mKd zHm-}hVg827%-8E9D{jRYNVsQ*F@SuvTnv@m9}ojvQ#QEt@%c?pFxA6B4f8j?;NI>; zoR&jVRtS`a>-EqNP^k+P0RYm+zf^l7UBl3C@Pe&RE92c1KC!PnsO$SG85Lglod34YI`m3|hJ**2o#i<0` zo|Okvus2L~g2ZsJC1_^jgc0C=zrBKAg4AwVn2Wv6Cv|XVdNEzsM{zu|z^%8C6wkIx z5HhPH2z3jke9q>xsv3<@FAuyQR9NzT@R#hyB)00eS9M$ZiSoGAB25Lnt|lR76&tNI zQ^}h80as{~CRp#K-Yj#9NiHR^r8jexz8P|2i_{b@G)X0QOpXhjp?MWf+}E4gimn-4 zu}O}3?p)K(vo*aXh%nv2i|s;-m^rR$>MaiL)*Drm9CBHh$Z&?Poi{u!sz!|8UT<@V*vHn zr4V}nB-^%bj;KWB(c`c`*<2jm3>@-|p3kFW76l9AgW00r$DYT|${`8%`mP*m*k@D6 zqb!M2XG$|Wp1i~^;58YpC}}husVdBDDzC7gc%~yIXa{zQ;i^mD;w-RVAaVLh2&?@V ziErWYIMgSY=)}MtWlrk>Yym+Go<4xUw=IZqRcwvpZC;I#Ng{yo*G5fMWDE7NFdR<+ zFdYhE@aTE$1}=oqqtZ`2ihNtvjiy%dWVs ww_DE8$6mubpgnd4wu;m(J0TN2x{ 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 literal 0 HcmV?d00001 From 20bca1f52701671866233294ab6ced9cd24b8cbb Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:12:39 +0000 Subject: [PATCH 27/72] Delete product-key-coa-windows-5922174a3df78cf5facd7f7c.png --- ...key-coa-windows-5922174a3df78cf5facd7f7c.png | Bin 44909 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 v.0.3/product-key-coa-windows-5922174a3df78cf5facd7f7c.png diff --git a/v.0.3/product-key-coa-windows-5922174a3df78cf5facd7f7c.png b/v.0.3/product-key-coa-windows-5922174a3df78cf5facd7f7c.png deleted file mode 100644 index 557238e8bd042509faf01655d3d2fb49cfd80e42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44909 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

$6o=RUMe^`}yqPLI-(almW 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%0D3@bw7Gf0YS72pTZ-aQiO0XN6v3Z90szD| zpUIR)y%VGf!y>pKrgc4-4irui4uX*qcL_i zMU7daD$nT#g7%8dcN9Q)OZp_F3p(DDPSa9p?5j-OC(6RYWb)EDg8F09ufxCJ>>%v= z>$m&+d(8iX`M>l7h}FZxgTb4YF!~L>2LO1%u)yI-umon$0I+4y{S^T4o3lro8`=sv z*3CQYj34(0r6Wzhd+a|-MN`95vT=Xfoh`j&F`-4$6Uy7uYQF`0~s8OJs4 zc|w|T&-9+D4j4+q+)_=v9u?mKd zHm-}hVg827%-8E9D{jRYNVsQ*F@SuvTnv@m9}ojvQ#QEt@%c?pFxA6B4f8j?;NI>; zoR&jVRtS`a>-EqNP^k+P0RYm+zf^l7UBl3C@Pe&RE92c1KC!PnsO$SG85Lglod34YI`m3|hJ**2o#i<0` zo|Okvus2L~g2ZsJC1_^jgc0C=zrBKAg4AwVn2Wv6Cv|XVdNEzsM{zu|z^%8C6wkIx z5HhPH2z3jke9q>xsv3<@FAuyQR9NzT@R#hyB)00eS9M$ZiSoGAB25Lnt|lR76&tNI zQ^}h80as{~CRp#K-Yj#9NiHR^r8jexz8P|2i_{b@G)X0QOpXhjp?MWf+}E4gimn-4 zu}O}3?p)K(vo*aXh%nv2i|s;-m^rR$>MaiL)*Drm9CBHh$Z&?Poi{u!sz!|8UT<@V*vHn zr4V}nB-^%bj;KWB(c`c`*<2jm3>@-|p3kFW76l9AgW00r$DYT|${`8%`mP*m*k@D6 zqb!M2XG$|Wp1i~^;58YpC}}husVdBDDzC7gc%~yIXa{zQ;i^mD;w-RVAaVLh2&?@V ziErWYIMgSY=)}MtWlrk>Yym+Go<4xUw=IZqRcwvpZC;I#Ng{yo*G5fMWDE7NFdR<+ zFdYhE@aTE$1}=oqqtZ`2ihNtvjiy%dWVs ww_DE8$6mubpgnd4wu;m(J0TN2x{ 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 From 152baad1230a56c3fed7c520dae9754b8d90acd2 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:13:44 +0000 Subject: [PATCH 28/72] Add files via upload --- v.0.3/Example_Microsoft_SN.png | Bin 0 -> 44909 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 v.0.3/Example_Microsoft_SN.png diff --git a/v.0.3/Example_Microsoft_SN.png b/v.0.3/Example_Microsoft_SN.png new file mode 100644 index 0000000000000000000000000000000000000000..557238e8bd042509faf01655d3d2fb49cfd80e42 GIT binary patch literal 44909 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

$6o=RUMe^`}yqPLI-(almW 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%0D3@bw7Gf0YS72pTZ-aQiO0XN6v3Z90szD| zpUIR)y%VGf!y>pKrgc4-4irui4uX*qcL_i zMU7daD$nT#g7%8dcN9Q)OZp_F3p(DDPSa9p?5j-OC(6RYWb)EDg8F09ufxCJ>>%v= z>$m&+d(8iX`M>l7h}FZxgTb4YF!~L>2LO1%u)yI-umon$0I+4y{S^T4o3lro8`=sv z*3CQYj34(0r6Wzhd+a|-MN`95vT=Xfoh`j&F`-4$6Uy7uYQF`0~s8OJs4 zc|w|T&-9+D4j4+q+)_=v9u?mKd zHm-}hVg827%-8E9D{jRYNVsQ*F@SuvTnv@m9}ojvQ#QEt@%c?pFxA6B4f8j?;NI>; zoR&jVRtS`a>-EqNP^k+P0RYm+zf^l7UBl3C@Pe&RE92c1KC!PnsO$SG85Lglod34YI`m3|hJ**2o#i<0` zo|Okvus2L~g2ZsJC1_^jgc0C=zrBKAg4AwVn2Wv6Cv|XVdNEzsM{zu|z^%8C6wkIx z5HhPH2z3jke9q>xsv3<@FAuyQR9NzT@R#hyB)00eS9M$ZiSoGAB25Lnt|lR76&tNI zQ^}h80as{~CRp#K-Yj#9NiHR^r8jexz8P|2i_{b@G)X0QOpXhjp?MWf+}E4gimn-4 zu}O}3?p)K(vo*aXh%nv2i|s;-m^rR$>MaiL)*Drm9CBHh$Z&?Poi{u!sz!|8UT<@V*vHn zr4V}nB-^%bj;KWB(c`c`*<2jm3>@-|p3kFW76l9AgW00r$DYT|${`8%`mP*m*k@D6 zqb!M2XG$|Wp1i~^;58YpC}}husVdBDDzC7gc%~yIXa{zQ;i^mD;w-RVAaVLh2&?@V ziErWYIMgSY=)}MtWlrk>Yym+Go<4xUw=IZqRcwvpZC;I#Ng{yo*G5fMWDE7NFdR<+ zFdYhE@aTE$1}=oqqtZ`2ihNtvjiy%dWVs ww_DE8$6mubpgnd4wu;m(J0TN2x{ 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 literal 0 HcmV?d00001 From bec8146b1b85ca47b369b898e20047d036fb1832 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:14:46 +0000 Subject: [PATCH 29/72] Rename Example_Generate_Random_Microsoft_SN.php to Example_Microsoft_SN_Generate_Random.php --- ..._Microsoft_SN.php => Example_Microsoft_SN_Generate_Random.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename v.0.3/{Example_Generate_Random_Microsoft_SN.php => Example_Microsoft_SN_Generate_Random.php} (100%) diff --git a/v.0.3/Example_Generate_Random_Microsoft_SN.php b/v.0.3/Example_Microsoft_SN_Generate_Random.php similarity index 100% rename from v.0.3/Example_Generate_Random_Microsoft_SN.php rename to v.0.3/Example_Microsoft_SN_Generate_Random.php From a443fdd53c976781be327f185e9234862faa1f57 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:16:09 +0000 Subject: [PATCH 30/72] Delete Example_Microsoft_SN_Generate_Random.php --- v.0.3/Example_Microsoft_SN_Generate_Random.php | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 v.0.3/Example_Microsoft_SN_Generate_Random.php diff --git a/v.0.3/Example_Microsoft_SN_Generate_Random.php b/v.0.3/Example_Microsoft_SN_Generate_Random.php deleted file mode 100644 index 009b12c..0000000 --- a/v.0.3/Example_Microsoft_SN_Generate_Random.php +++ /dev/null @@ -1,8 +0,0 @@ -SetLength(25); -$CANG->SetType(5); -$return = $CANG->Generate_String(); -echo implode('-',str_split($return['code_base'], 5)); -?> From 899f19d5c4052e330610f0cc446548b8f73fa55e Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:17:09 +0000 Subject: [PATCH 31/72] Create Example_Microsoft_SN_Generate_Random.php --- v.0.3/Example_Microsoft_SN_Generate_Random.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 v.0.3/Example_Microsoft_SN_Generate_Random.php diff --git a/v.0.3/Example_Microsoft_SN_Generate_Random.php b/v.0.3/Example_Microsoft_SN_Generate_Random.php new file mode 100644 index 0000000..009b12c --- /dev/null +++ b/v.0.3/Example_Microsoft_SN_Generate_Random.php @@ -0,0 +1,8 @@ +SetLength(25); +$CANG->SetType(5); +$return = $CANG->Generate_String(); +echo implode('-',str_split($return['code_base'], 5)); +?> From 58e351ffb641341240b106aca5da6c9ee2720055 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Thu, 16 Nov 2017 22:26:53 +0000 Subject: [PATCH 32/72] Update CANG.php --- v.0.3/CANG.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/v.0.3/CANG.php b/v.0.3/CANG.php index eb37b55..f216794 100644 --- a/v.0.3/CANG.php +++ b/v.0.3/CANG.php @@ -8,7 +8,12 @@ class CANG { protected $code_max_type = 8; public function __construct(){ - set_time_limit(0); + /* + Nothing to do here but if you need to use it with CI must write : + class CANG extends CI_Library {} + and remove the double back slash below + */ + //parent::__construct(); } public function SetLength($SetLength=FALSE){ From 9ccb7ea6a8f59a63f9a72312f1da2d5bdffdac12 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:06:38 +0000 Subject: [PATCH 33/72] Update CANG to check if function_exists('bcpow') Reducing error of "bcpow" check if the function exist. Use the function for calculation else use standard "pow", because not everywhere it's possible to use it. --- v.0.3/CANG.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/v.0.3/CANG.php b/v.0.3/CANG.php index f216794..277321a 100644 --- a/v.0.3/CANG.php +++ b/v.0.3/CANG.php @@ -30,7 +30,12 @@ public function SetType($SetType=FALSE){ public function CodeCountRange($code_char_range=[]){ $count_characters = count($code_char_range); - return pow($count_characters, $this->default_code_length); + if(function_exists('bcpow')){ + return bcpow($count_characters, $this->default_code_length); + }else{ + return pow($count_characters, $this->default_code_length); + } + } public function CodeTypes(){ @@ -274,9 +279,16 @@ public function Generate_ID($GenerateID){ $code_id = ($GenerateID - $one); } for($length=($this->default_code_length - $one);$length>=0;$length--){ - $bcpow = bcpow($code_char_count, $length); - $possition = floor($code_id / $bcpow); - $code_id = $code_id - ($possition * $bcpow); + if(function_exists('bcpow')){ + $bcpow = bcpow($code_char_count, $length); + $possition = floor($code_id / $bcpow); + $code_id = $code_id - ($possition * $bcpow); + }else{ + $pow = pow($code_char_count, $length); + $possition = floor($code_id / $pow); + $code_id = $code_id - ($possition * $pow); + } + $this->code_char_base[$length] = $code_char_range[$possition]; } $this->CodeCountNumber(); From e2fb7222d64211f8ae231dd43defa147cdd22f3f Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:16:26 +0000 Subject: [PATCH 34/72] Update Example_Microsoft_SN_Generate_Random.php --- v.0.3/Example_Microsoft_SN_Generate_Random.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/v.0.3/Example_Microsoft_SN_Generate_Random.php b/v.0.3/Example_Microsoft_SN_Generate_Random.php index 009b12c..cf285b4 100644 --- a/v.0.3/Example_Microsoft_SN_Generate_Random.php +++ b/v.0.3/Example_Microsoft_SN_Generate_Random.php @@ -4,5 +4,12 @@ $CANG->SetLength(25); $CANG->SetType(5); $return = $CANG->Generate_String(); -echo implode('-',str_split($return['code_base'], 5)); +foreach ($return AS $return_key=>$return_value){ + if($return_key=='code_base'){ + $new_return[$return_key] = implode('-',str_split($return_value, 5)); + }else{ + $new_return[$return_key] = $return_value; + } +} +print_r($new_return); ?> From 807e7dda6059bb6adf7b585f28c6bb0386d63950 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:21:30 +0000 Subject: [PATCH 35/72] Create Example_Microsoft_SN_Generate_ID.php --- v.0.3/Example_Microsoft_SN_Generate_ID.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 v.0.3/Example_Microsoft_SN_Generate_ID.php diff --git a/v.0.3/Example_Microsoft_SN_Generate_ID.php b/v.0.3/Example_Microsoft_SN_Generate_ID.php new file mode 100644 index 0000000..7ad3cc8 --- /dev/null +++ b/v.0.3/Example_Microsoft_SN_Generate_ID.php @@ -0,0 +1,15 @@ +SetLength(25); +$CANG->SetType(5); +$return = $CANG->Generate_ID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID +foreach ($return AS $return_key=>$return_value){ + if($return_key=='code_base'){ + $new_return[$return_key] = implode('-',str_split($return_value, 5)); + }else{ + $new_return[$return_key] = $return_value; + } +} +print_r($new_return); +?> From 8ad34d0ffa2946a23466247c7307468177a45a1b Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:41:09 +0000 Subject: [PATCH 36/72] Create Example_Generate_ID_JSON.php --- v.0.3/Example_Generate_ID_JSON.php | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 v.0.3/Example_Generate_ID_JSON.php diff --git a/v.0.3/Example_Generate_ID_JSON.php b/v.0.3/Example_Generate_ID_JSON.php new file mode 100644 index 0000000..4972e05 --- /dev/null +++ b/v.0.3/Example_Generate_ID_JSON.php @@ -0,0 +1,9 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID +header("Content-type:application/json"); +echo json_encode($return,true); +?> From c6435f5fb2111f4e029bc22795f514160e68466d Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:41:49 +0000 Subject: [PATCH 37/72] Create Example_Generate_Random_JSON.php --- v.0.3/Example_Generate_Random_JSON.php | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 v.0.3/Example_Generate_Random_JSON.php diff --git a/v.0.3/Example_Generate_Random_JSON.php b/v.0.3/Example_Generate_Random_JSON.php new file mode 100644 index 0000000..a00d466 --- /dev/null +++ b/v.0.3/Example_Generate_Random_JSON.php @@ -0,0 +1,9 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_String(); +header("Content-type:application/json"); +echo json_encode($return,true); +?> From 99e21a10841b3ce6c94a66b0b95674fc8101dff5 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:42:28 +0000 Subject: [PATCH 38/72] Create Example_Generate_String_JSON.php --- v.0.3/Example_Generate_String_JSON.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 v.0.3/Example_Generate_String_JSON.php diff --git a/v.0.3/Example_Generate_String_JSON.php b/v.0.3/Example_Generate_String_JSON.php new file mode 100644 index 0000000..f6a72c5 --- /dev/null +++ b/v.0.3/Example_Generate_String_JSON.php @@ -0,0 +1,12 @@ +SetLength(8); +$CANG->SetType(5); +$CANG->CodeInput(); +$return[1] = $CANG->Generate_String(); +$CANG->CodeInput($return[1]['code_base']); +$return[] = $CANG->Generate_String(); +header("Content-type:application/json"); +echo json_encode($return,true); +?> From 5dd503930db0520ce84d34159c699266917baf2a Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:43:04 +0000 Subject: [PATCH 39/72] Create Example_Microsoft_SN_Generate_ID_JSON.php --- v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php diff --git a/v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php b/v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php new file mode 100644 index 0000000..bf905ba --- /dev/null +++ b/v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php @@ -0,0 +1,16 @@ +SetLength(25); +$CANG->SetType(5); +$return = $CANG->Generate_ID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID +foreach ($return AS $return_key=>$return_value){ + if($return_key=='code_base'){ + $new_return[$return_key] = implode('-',str_split($return_value, 5)); + }else{ + $new_return[$return_key] = $return_value; + } +} +header("Content-type:application/json"); +echo json_encode($new_return,true); +?> From 9716714061c9ccfafe789c467a524b2c971f8b88 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 01:43:41 +0000 Subject: [PATCH 40/72] Create Example_Microsoft_SN_Generate_Random_JSON.php --- ...Example_Microsoft_SN_Generate_Random_JSON.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php diff --git a/v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php new file mode 100644 index 0000000..848b6eb --- /dev/null +++ b/v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php @@ -0,0 +1,16 @@ +SetLength(25); +$CANG->SetType(5); +$return = $CANG->Generate_String(); +foreach ($return AS $return_key=>$return_value){ + if($return_key=='code_base'){ + $new_return[$return_key] = implode('-',str_split($return_value, 5)); + }else{ + $new_return[$return_key] = $return_value; + } +} +header("Content-type:application/json"); +echo json_encode($new_return,true) +?> From baa759ca5cf2be3046e7812c10de28918c2b99fc Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Sat, 2 Dec 2017 14:21:52 +0000 Subject: [PATCH 41/72] Rename README.md to v.0.3/README.md --- README.md => v.0.3/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.md => v.0.3/README.md (100%) diff --git a/README.md b/v.0.3/README.md similarity index 100% rename from README.md rename to v.0.3/README.md From 40d5c31255a08b2eeac0f20a0257936e836ca6b4 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 6 Dec 2017 08:18:25 +0000 Subject: [PATCH 42/72] Update Example_Generate_ID.php --- v.0.3/Example_Generate_ID.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v.0.3/Example_Generate_ID.php b/v.0.3/Example_Generate_ID.php index d182982..f32c2f5 100644 --- a/v.0.3/Example_Generate_ID.php +++ b/v.0.3/Example_Generate_ID.php @@ -3,6 +3,6 @@ $CANG = new CANG; $CANG->SetLength(8); $CANG->SetType(5); -$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID +$return = $CANG->Generate_ID(249996);//You should be able to generate the key by any input ID print_r($return); ?> From 55db5064f1c42e2e87975dad41e710faa4dcdb92 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 6 Dec 2017 09:26:55 +0000 Subject: [PATCH 43/72] Update CANG.php -> replace protected by public Replace protected by public in : protected $code_max_type. Because of issue when using : $this->CANG->code_max_type --- v.0.3/CANG.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v.0.3/CANG.php b/v.0.3/CANG.php index 277321a..70456ff 100644 --- a/v.0.3/CANG.php +++ b/v.0.3/CANG.php @@ -5,7 +5,7 @@ class CANG { public $default_code_type = 1; public $run_default_code = TRUE; public $run_random_code = TRUE; - protected $code_max_type = 8; + public $code_max_type = 8; public function __construct(){ /* From bd6b050f6d759894ffe042dfa8638fed79512d23 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 13:38:52 +0000 Subject: [PATCH 44/72] Update CANG.php Issue with strings AAAAACPZ next code was -> AAAAACP1 but it should be AAAAACP0 and after AAAAACP1. Issue fixed! --- v.0.3/CANG.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/v.0.3/CANG.php b/v.0.3/CANG.php index 70456ff..5a2842f 100644 --- a/v.0.3/CANG.php +++ b/v.0.3/CANG.php @@ -140,11 +140,8 @@ public function CodeCreateNext(){ if("$code_str_split[$n]" != "$code_char_range_end"){ // If the previous character is different from code_char_range_end, it increments it and clears the current and subsequent characters // If the previous character is the first one, it also works, because it increments it and zeroes the others - if(empty($code_char_range[$code_str_pos])){ - $code_str_split[$n] = settype($code_char_range[$code_str_pos],'string'); - }else{ - $code_str_split[$n] = $code_char_range[$code_str_pos]; - } + $code_str_split[$n] = $code_char_range[$code_str_pos]; + for($j = $i; $j < count($code_str_split); $j++){ $code_str_split[$j] = $code_char_range_start; } @@ -154,11 +151,7 @@ public function CodeCreateNext(){ }else{ // calculates the next character, ie, increments the current character $code_str_pos = $this->Search("$code_str_split[$i]")+1; - if(empty($code_char_range[$code_str_pos])){ - $code_str_split[$i] = settype($code_char_range[$code_str_pos],'string'); - }else{ - $code_str_split[$i] = $code_char_range[$code_str_pos]; - } + $code_str_split[$i] = $code_char_range[$code_str_pos]; if($i == 0){ // If it is the first character, it means that the others are code_char_range_end // That is, he zeroes them From 410492ee3c24a8c0218ea76d888c7aaf6a229fe9 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 13:56:27 +0000 Subject: [PATCH 45/72] Rename v.0.3/CANG.php to v.0.3/Base_CANG_Generators/CANG.php --- v.0.3/{ => Base_CANG_Generators}/CANG.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename v.0.3/{ => Base_CANG_Generators}/CANG.php (100%) diff --git a/v.0.3/CANG.php b/v.0.3/Base_CANG_Generators/CANG.php similarity index 100% rename from v.0.3/CANG.php rename to v.0.3/Base_CANG_Generators/CANG.php From d87b3aa6b55818c5f4cb61ed699eb4ce39eb88d1 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 13:58:27 +0000 Subject: [PATCH 46/72] Update and rename v.0.3/Example_Generate_ID.php to v.0.3/Base_Examples_NoMySQL/Example_Generate_ID.php --- v.0.3/Base_Examples_NoMySQL/Example_Generate_ID.php | 8 ++++++++ v.0.3/Example_Generate_ID.php | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 v.0.3/Base_Examples_NoMySQL/Example_Generate_ID.php delete mode 100644 v.0.3/Example_Generate_ID.php diff --git a/v.0.3/Base_Examples_NoMySQL/Example_Generate_ID.php b/v.0.3/Base_Examples_NoMySQL/Example_Generate_ID.php new file mode 100644 index 0000000..bc08463 --- /dev/null +++ b/v.0.3/Base_Examples_NoMySQL/Example_Generate_ID.php @@ -0,0 +1,8 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> diff --git a/v.0.3/Example_Generate_ID.php b/v.0.3/Example_Generate_ID.php deleted file mode 100644 index f32c2f5..0000000 --- a/v.0.3/Example_Generate_ID.php +++ /dev/null @@ -1,8 +0,0 @@ -SetLength(8); -$CANG->SetType(5); -$return = $CANG->Generate_ID(249996);//You should be able to generate the key by any input ID -print_r($return); -?> From d58f02fca57b1f40ab34374538272677245b7b0b Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 13:59:40 +0000 Subject: [PATCH 47/72] Update and rename v.0.3/Example_Generate_ID_JSON.php to v.0.3/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php --- v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_ID_JSON.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_ID_JSON.php (84%) diff --git a/v.0.3/Example_Generate_ID_JSON.php b/v.0.3/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php similarity index 84% rename from v.0.3/Example_Generate_ID_JSON.php rename to v.0.3/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php index 4972e05..7f7170c 100644 --- a/v.0.3/Example_Generate_ID_JSON.php +++ b/v.0.3/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php @@ -1,5 +1,5 @@ SetLength(8); $CANG->SetType(5); From 73fc930699dbd9055c85167dd302ff42f4dc0ac6 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:01:14 +0000 Subject: [PATCH 48/72] Update and rename v.0.3/Example_Generate_Random.php to v.0.3/Base_Examples_NoMySQL/Example_Generate_Random.php --- v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_Random.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_Random.php (72%) diff --git a/v.0.3/Example_Generate_Random.php b/v.0.3/Base_Examples_NoMySQL/Example_Generate_Random.php similarity index 72% rename from v.0.3/Example_Generate_Random.php rename to v.0.3/Base_Examples_NoMySQL/Example_Generate_Random.php index 3d87956..d9185db 100644 --- a/v.0.3/Example_Generate_Random.php +++ b/v.0.3/Base_Examples_NoMySQL/Example_Generate_Random.php @@ -1,5 +1,5 @@ SetLength(8); $CANG->SetType(5); From 637665cdd459173c554d34543c4cea40c04ba7e7 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:02:48 +0000 Subject: [PATCH 49/72] Update and rename v.0.3/Example_Generate_Random_JSON.php to v.0.3/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php --- .../Example_Generate_Random_JSON.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_Random_JSON.php (79%) diff --git a/v.0.3/Example_Generate_Random_JSON.php b/v.0.3/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php similarity index 79% rename from v.0.3/Example_Generate_Random_JSON.php rename to v.0.3/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php index a00d466..ba850c8 100644 --- a/v.0.3/Example_Generate_Random_JSON.php +++ b/v.0.3/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php @@ -1,5 +1,5 @@ SetLength(8); $CANG->SetType(5); From f48478b81463cd10d99a5314eaa2e43dcd56bac3 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:04:38 +0000 Subject: [PATCH 50/72] Update and rename v.0.3/Example_Generate_String.php to v.0.3/Base_Examples_NoMySQL/Example_Generate_String.php --- v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_String.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) rename v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_String.php (83%) diff --git a/v.0.3/Example_Generate_String.php b/v.0.3/Base_Examples_NoMySQL/Example_Generate_String.php similarity index 83% rename from v.0.3/Example_Generate_String.php rename to v.0.3/Base_Examples_NoMySQL/Example_Generate_String.php index a8298f4..a843dd4 100644 --- a/v.0.3/Example_Generate_String.php +++ b/v.0.3/Base_Examples_NoMySQL/Example_Generate_String.php @@ -1,12 +1,10 @@ SetLength(8); $CANG->SetType(5); - $CANG->CodeInput(); $return[1] = $CANG->Generate_String(); - $CANG->CodeInput($return[1]['code_base']); $return[] = $CANG->Generate_String(); print_r($return); From b35a15efd1fc06d6989833f67c293e3d60870db7 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:05:58 +0000 Subject: [PATCH 51/72] Update and rename v.0.3/Example_Generate_String_JSON.php to v.0.3/Base_Examples_NoMySQL/Example_Generate_String_JSON.php --- .../Example_Generate_String_JSON.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename v.0.3/{ => Base_Examples_NoMySQL}/Example_Generate_String_JSON.php (86%) diff --git a/v.0.3/Example_Generate_String_JSON.php b/v.0.3/Base_Examples_NoMySQL/Example_Generate_String_JSON.php similarity index 86% rename from v.0.3/Example_Generate_String_JSON.php rename to v.0.3/Base_Examples_NoMySQL/Example_Generate_String_JSON.php index f6a72c5..8050c54 100644 --- a/v.0.3/Example_Generate_String_JSON.php +++ b/v.0.3/Base_Examples_NoMySQL/Example_Generate_String_JSON.php @@ -1,5 +1,5 @@ SetLength(8); $CANG->SetType(5); From 77cbb96e25fc7bdeff90da3a1d5a3ccc423a86d1 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:08:09 +0000 Subject: [PATCH 52/72] Update and rename v.0.3/Example_Microsoft_SN_Generate_ID.php to v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php --- .../Example_Microsoft_SN_Generate_ID.php | 6 ++++++ v.0.3/Example_Microsoft_SN_Generate_ID.php | 15 --------------- 2 files changed, 6 insertions(+), 15 deletions(-) create mode 100644 v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php delete mode 100644 v.0.3/Example_Microsoft_SN_Generate_ID.php diff --git a/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php new file mode 100644 index 0000000..02f3262 --- /dev/null +++ b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php @@ -0,0 +1,6 @@ +byID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> diff --git a/v.0.3/Example_Microsoft_SN_Generate_ID.php b/v.0.3/Example_Microsoft_SN_Generate_ID.php deleted file mode 100644 index 7ad3cc8..0000000 --- a/v.0.3/Example_Microsoft_SN_Generate_ID.php +++ /dev/null @@ -1,15 +0,0 @@ -SetLength(25); -$CANG->SetType(5); -$return = $CANG->Generate_ID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID -foreach ($return AS $return_key=>$return_value){ - if($return_key=='code_base'){ - $new_return[$return_key] = implode('-',str_split($return_value, 5)); - }else{ - $new_return[$return_key] = $return_value; - } -} -print_r($new_return); -?> From 91d84981e0683e13293b410f9c8b7c819e99e8d3 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:09:15 +0000 Subject: [PATCH 53/72] Update and rename v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php to v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php --- .../Example_Microsoft_SN_Generate_ID_JSON.php | 7 +++++++ v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php | 16 ---------------- 2 files changed, 7 insertions(+), 16 deletions(-) create mode 100644 v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php delete mode 100644 v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php diff --git a/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php new file mode 100644 index 0000000..55a9877 --- /dev/null +++ b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php @@ -0,0 +1,7 @@ +byID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID +header("Content-type:application/json"); +echo json_encode($return,true); +?> diff --git a/v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php b/v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php deleted file mode 100644 index bf905ba..0000000 --- a/v.0.3/Example_Microsoft_SN_Generate_ID_JSON.php +++ /dev/null @@ -1,16 +0,0 @@ -SetLength(25); -$CANG->SetType(5); -$return = $CANG->Generate_ID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID -foreach ($return AS $return_key=>$return_value){ - if($return_key=='code_base'){ - $new_return[$return_key] = implode('-',str_split($return_value, 5)); - }else{ - $new_return[$return_key] = $return_value; - } -} -header("Content-type:application/json"); -echo json_encode($new_return,true); -?> From 978bde7caa42430bfc0705a4b5307da94bc046da Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:11:00 +0000 Subject: [PATCH 54/72] Update and rename v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php to v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php --- ...Example_Microsoft_SN_Generate_Random_JSON.php | 6 ++++++ ...Example_Microsoft_SN_Generate_Random_JSON.php | 16 ---------------- 2 files changed, 6 insertions(+), 16 deletions(-) create mode 100644 v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php delete mode 100644 v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php diff --git a/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php new file mode 100644 index 0000000..e38b1f0 --- /dev/null +++ b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php @@ -0,0 +1,6 @@ +byRAND();//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> diff --git a/v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php deleted file mode 100644 index 848b6eb..0000000 --- a/v.0.3/Example_Microsoft_SN_Generate_Random_JSON.php +++ /dev/null @@ -1,16 +0,0 @@ -SetLength(25); -$CANG->SetType(5); -$return = $CANG->Generate_String(); -foreach ($return AS $return_key=>$return_value){ - if($return_key=='code_base'){ - $new_return[$return_key] = implode('-',str_split($return_value, 5)); - }else{ - $new_return[$return_key] = $return_value; - } -} -header("Content-type:application/json"); -echo json_encode($new_return,true) -?> From 8e436ff11ff4801567d97f7969119eee62e9765a Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:11:53 +0000 Subject: [PATCH 55/72] Update and rename v.0.3/Example_Microsoft_SN_Generate_Random.php to v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php --- .../Example_Microsoft_SN_Generate_Random.php | 6 ++++++ v.0.3/Example_Microsoft_SN_Generate_Random.php | 15 --------------- 2 files changed, 6 insertions(+), 15 deletions(-) create mode 100644 v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php delete mode 100644 v.0.3/Example_Microsoft_SN_Generate_Random.php diff --git a/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php new file mode 100644 index 0000000..e38b1f0 --- /dev/null +++ b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php @@ -0,0 +1,6 @@ +byRAND();//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> diff --git a/v.0.3/Example_Microsoft_SN_Generate_Random.php b/v.0.3/Example_Microsoft_SN_Generate_Random.php deleted file mode 100644 index cf285b4..0000000 --- a/v.0.3/Example_Microsoft_SN_Generate_Random.php +++ /dev/null @@ -1,15 +0,0 @@ -SetLength(25); -$CANG->SetType(5); -$return = $CANG->Generate_String(); -foreach ($return AS $return_key=>$return_value){ - if($return_key=='code_base'){ - $new_return[$return_key] = implode('-',str_split($return_value, 5)); - }else{ - $new_return[$return_key] = $return_value; - } -} -print_r($new_return); -?> From 5a9c79dbfa9b56c72d940e7a22144bfd5d918d3f Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:12:32 +0000 Subject: [PATCH 56/72] Update Example_Microsoft_SN_Generate_Random_JSON.php --- .../Example_Microsoft_SN_Generate_Random_JSON.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php index e38b1f0..d41c3a5 100644 --- a/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php +++ b/v.0.3/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php @@ -2,5 +2,6 @@ include('../Base_CANG_Generators/MS_G.php'); $MS_G = new MS_G; $return = $MS_G->byRAND();//In 30 seconds you should be able to generate the key by this ID -print_r($return); +header("Content-type:application/json"); +echo json_encode($return,true) ?> From 9a472c18779f17f281470957ad4b05db853f583b Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Fri, 8 Dec 2017 14:36:00 +0000 Subject: [PATCH 57/72] Create MS_G.php --- v.0.3/Base_CANG_Generators/MS_G.php | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 v.0.3/Base_CANG_Generators/MS_G.php diff --git a/v.0.3/Base_CANG_Generators/MS_G.php b/v.0.3/Base_CANG_Generators/MS_G.php new file mode 100644 index 0000000..3a4a2ad --- /dev/null +++ b/v.0.3/Base_CANG_Generators/MS_G.php @@ -0,0 +1,56 @@ +SetLength(25); + $this->SetType(5); + } + + public function byID($NUM_ID){ + foreach ($this->Generate_ID($NUM_ID) AS $return_key=>$return_value){ + if($return_key=='code_base'){ + $new_return[$return_key] = implode('-',str_split($return_value, 5)); + }elseif($return_key=='code_description'){ + $new_return[$return_key] = str_replace('Megaupload','Microsoft',$return_value); + }else{ + $new_return[$return_key] = $return_value; + } + } + return $new_return; + } + + public function byRAND(){ + foreach($this->Generate_String() AS $return_key=>$return_value){ + if($return_key=='code_base'){ + $new_return[$return_key] = implode('-',str_split($return_value, 5)); + }elseif($return_key=='code_description'){ + $new_return[$return_key] = str_replace('Megaupload','Microsoft',$return_value); + }else{ + $new_return[$return_key] = $return_value; + } + } + return $new_return; + } + + public function bySTRING($STRING=''){ + if($STRING){ + $Input = str_replace('-','',$STRING); + }else{ + $Input = ''; + } + $this->CodeInput($Input); + foreach($this->Generate_String() AS $return_key=>$return_value){ + if($return_key=='code_base'){ + $new_return[$return_key] = implode('-',str_split($return_value, 5)); + }elseif($return_key=='code_description'){ + $new_return[$return_key] = str_replace('Megaupload','Microsoft',$return_value); + }else{ + $new_return[$return_key] = $return_value; + } + } + return $new_return; + } +} +?> From 5ec42acb8139b658956a894af5a4d79f342f22e3 Mon Sep 17 00:00:00 2001 From: Lukas Stribrny Date: Wed, 3 Jan 2018 13:00:06 +0000 Subject: [PATCH 58/72] Update MS_G.php --- v.0.3/Base_CANG_Generators/MS_G.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v.0.3/Base_CANG_Generators/MS_G.php b/v.0.3/Base_CANG_Generators/MS_G.php index 3a4a2ad..56ccdd0 100644 --- a/v.0.3/Base_CANG_Generators/MS_G.php +++ b/v.0.3/Base_CANG_Generators/MS_G.php @@ -1,5 +1,5 @@ Date: Fri, 5 Dec 2025 11:20:04 +0100 Subject: [PATCH 59/72] A New Version of Universal and Complex Key Generator --- v.0.4/UniversalKeyGenerator.php | 256 ++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 v.0.4/UniversalKeyGenerator.php diff --git a/v.0.4/UniversalKeyGenerator.php b/v.0.4/UniversalKeyGenerator.php new file mode 100644 index 0000000..193c275 --- /dev/null +++ b/v.0.4/UniversalKeyGenerator.php @@ -0,0 +1,256 @@ +generateRandomString(8, 'UPPERCASE'); + } + + /** + * Generate a random Username (8-12 characters, mixed case + numbers) + */ + public function generateUsername() { + return $this->generateRandomString(mt_rand(8, 12), 'MIXED'); + } + + /** + * Generate a random Upload URI (format: /upload/XXXXXXXX) + */ + public function generateUploadUri() { + $randomPart = $this->generateRandomString(8, 'UPPERCASE'); + return "/upload/{$randomPart}"; + } + + /** + * Generate a random User Password (max 16 characters, any letters) + */ + public function generateUserPassword() { + $length = mt_rand(8, 16); + $charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*'; + return $this->generateCustomString($length, $charset); + } + + /** + * Generate a Product Key (format: XXXXX-XXXXX-XXXXX-XXXXX-XXXXX) + */ + public function generateProductKey() { + $segments = []; + for ($i = 0; $i < 5; $i++) { + $segments[] = $this->generateRandomString(5, 'UPPERCASE'); + } + return implode('-', $segments); + } + + /** + * Get next API Key based on current + */ + public function nextApiKey($current = null) { + if ($current === null && isset($this->currentState['apiKey'])) { + $current = $this->currentState['apiKey']; + } + $next = $this->incrementString($current ?? $this->generateApiKey(), 'UPPERCASE'); + $this->currentState['apiKey'] = $next; + return $next; + } + + /** + * Get previous API Key based on current + */ + public function previousApiKey($current = null) { + if ($current === null && isset($this->currentState['apiKey'])) { + $current = $this->currentState['apiKey']; + } + $prev = $this->decrementString($current ?? $this->generateApiKey(), 'UPPERCASE'); + $this->currentState['apiKey'] = $prev; + return $prev; + } + + /** + * Get next Product Key + */ + public function nextProductKey($current = null) { + if ($current === null && isset($this->currentState['productKey'])) { + $current = $this->currentState['productKey']; + } + $next = $this->incrementProductKey($current ?? $this->generateProductKey()); + $this->currentState['productKey'] = $next; + return $next; + } + + /** + * Get previous Product Key + */ + public function previousProductKey($current = null) { + if ($current === null && isset($this->currentState['productKey'])) { + $current = $this->currentState['productKey']; + } + $prev = $this->decrementProductKey($current ?? $this->generateProductKey()); + $this->currentState['productKey'] = $prev; + return $prev; + } + + /** + * Helper: Generate random string of specified type + */ + private function generateRandomString($length, $type = 'UPPERCASE') { + $charsets = [ + 'UPPERCASE' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + 'LOWERCASE' => 'abcdefghijklmnopqrstuvwxyz', + 'MIXED' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', + 'NUMBERS' => '0123456789' + ]; + + $charset = $charsets[$type] ?? $charsets['MIXED']; + $result = ''; + $maxIndex = strlen($charset) - 1; + + for ($i = 0; $i < $length; $i++) { + $result .= $charset[mt_rand(0, $maxIndex)]; + } + + return $result; + } + + /** + * Helper: Generate custom string with custom charset + */ + private function generateCustomString($length, $charset) { + $result = ''; + $maxIndex = strlen($charset) - 1; + + for ($i = 0; $i < $length; $i++) { + $result .= $charset[mt_rand(0, $maxIndex)]; + } + + return $result; + } + + /** + * Helper: Increment string (A->B, Z->AA) + */ + private function incrementString($str, $type = 'UPPERCASE') { + $charset = ($type === 'UPPERCASE') ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' : 'abcdefghijklmnopqrstuvwxyz'; + $result = str_split($str); + $carry = 1; + + for ($i = count($result) - 1; $i >= 0 && $carry; $i--) { + $pos = strpos($charset, $result[$i]); + if ($pos !== false) { + $pos += $carry; + if ($pos >= strlen($charset)) { + $result[$i] = $charset[0]; + $carry = 1; + } else { + $result[$i] = $charset[$pos]; + $carry = 0; + } + } + } + + if ($carry) { + array_unshift($result, $charset[0]); + } + + return implode('', $result); + } + + /** + * Helper: Decrement string (B->A, AA->Z) + */ + private function decrementString($str, $type = 'UPPERCASE') { + $charset = ($type === 'UPPERCASE') ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' : 'abcdefghijklmnopqrstuvwxyz'; + $result = str_split($str); + $borrow = 1; + + for ($i = count($result) - 1; $i >= 0 && $borrow; $i--) { + $pos = strpos($charset, $result[$i]); + if ($pos !== false) { + $pos -= $borrow; + if ($pos < 0) { + $result[$i] = $charset[strlen($charset) - 1]; + $borrow = 1; + } else { + $result[$i] = $charset[$pos]; + $borrow = 0; + } + } + } + + if (count($result) > 1 && $result[0] === $charset[strlen($charset) - 1]) { + array_shift($result); + } + + return implode('', $result); + } + + /** + * Helper: Increment Product Key + */ + private function incrementProductKey($key) { + $segments = explode('-', $key); + $carry = 1; + + for ($i = count($segments) - 1; $i >= 0 && $carry; $i--) { + $segments[$i] = $this->incrementString($segments[$i], 'UPPERCASE'); + if ($segments[$i] !== 'A' || $segments[$i] === 'AAAAAA') { + $carry = 0; + } + } + + return implode('-', $segments); + } + + /** + * Helper: Decrement Product Key + */ + private function decrementProductKey($key) { + $segments = explode('-', $key); + $borrow = 1; + + for ($i = count($segments) - 1; $i >= 0 && $borrow; $i--) { + $prev = $segments[$i]; + $segments[$i] = $this->decrementString($segments[$i], 'UPPERCASE'); + if ($segments[$i] !== $prev) { + $borrow = 0; + } + } + + return implode('-', $segments); + } + + /** + * Reset current state + */ + public function resetState() { + $this->currentState = []; + } +} + +// Example Usage: +if (php_sapi_name() === 'cli') { + $generator = new UniversalKeyGenerator(); + + echo "=== RANDOM GENERATION ===\n"; + echo "API Key: " . $generator->generateApiKey() . "\n"; + echo "Username: " . $generator->generateUsername() . "\n"; + echo "Upload URI: " . $generator->generateUploadUri() . "\n"; + echo "Password: " . $generator->generateUserPassword() . "\n"; + echo "Product Key: " . $generator->generateProductKey() . "\n\n"; + + echo "=== SEQUENTIAL GENERATION ===\n"; + $apiKey = $generator->generateApiKey(); + echo "Current API Key: $apiKey\n"; + echo "Next API Key: " . $generator->nextApiKey($apiKey) . "\n"; + echo "Previous API Key: " . $generator->previousApiKey() . "\n\n"; + + $productKey = $generator->generateProductKey(); + echo "Current Product Key: $productKey\n"; + echo "Next Product Key: " . $generator->nextProductKey($productKey) . "\n"; + echo "Previous Product Key: " . $generator->previousProductKey() . "\n"; +} +?> \ No newline at end of file From fa13bf2dde6f2fd85f6c33685ca817ddea00530d Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Fri, 5 Dec 2025 11:49:04 +0100 Subject: [PATCH 60/72] Another version to Collection --- v.0.4/ComplexKeyGenerator.php | 173 ++++++++++++++++++ ...rSoft.ValidateTest.ComplexKeyGenerator.php | 28 +++ ...erSoft.ValidateTest.UniversalGenerator.php | 26 +++ ...ft.ValidateTest.UniversalGenerator.php.bak | 0 ...oft.ValidateTest.UniversalKeyGenerator.php | 22 +++ 5 files changed, 249 insertions(+) create mode 100644 v.0.4/ComplexKeyGenerator.php create mode 100644 v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php create mode 100644 v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php create mode 100644 v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php.bak create mode 100644 v.0.4/SilverSoft.ValidateTest.UniversalKeyGenerator.php diff --git a/v.0.4/ComplexKeyGenerator.php b/v.0.4/ComplexKeyGenerator.php new file mode 100644 index 0000000..670e9ad --- /dev/null +++ b/v.0.4/ComplexKeyGenerator.php @@ -0,0 +1,173 @@ + 'abcdefghijklmnopqrstuvwxyz', + 'upper' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + 'digits' => '0123456789', + 'special' => '!@#$%&*()-_=+[]{}<>?' + ]; + + // Secure random character from string + protected static function randomChar(string $chars): string + { + $max = mb_strlen($chars, '8bit') - 1; + return $chars[random_int(0, $max)]; + } + + // Build random string from provided charset + protected static function randomString(int $length, string $charset): string + { + if ($length <= 0) { + return ''; + } + $out = ''; + $clen = strlen($charset); + if ($clen === 0) { + throw new InvalidArgumentException('Charset must not be empty'); + } + for ($i = 0; $i < $length; $i++) { + $out .= $charset[random_int(0, $clen - 1)]; + } + return $out; + } + + // Generate generic key (hex, base64 or custom char set) + public static function generateKey(int $length = 32, string $type = 'hex'): string + { + if ($length <= 0) return ''; + + if ($type === 'hex') { + // return hex string (length is number of chars) + $bytes = random_bytes((int)ceil($length / 2)); + return substr(bin2hex($bytes), 0, $length); + } + if ($type === 'base64') { + $bytes = random_bytes($length); + return rtrim(strtr(base64_encode($bytes), '+/', '-_'), '='); + } + // custom: use provided type as charset + return self::randomString($length, $type); + } + + // Generate username: optional prefix, random suffix; length is total length if provided + public static function generateUsername(string $prefix = '', int $length = 10, string $sep = '_'): string + { + $prefix = preg_replace('/[^A-Za-z0-9]/', '', $prefix); + $available = $length - strlen($prefix); + if ($available <= 0) { + return substr($prefix, 0, $length); + } + // small adjective + noun fallback arrays + $adjectives = ['quick','clever','silent','bright','brave','calm','wild','mighty']; + $nouns = ['fox','owl','hawk','pixel','node','byte','raven','spark']; + $part = $adjectives[random_int(0, count($adjectives)-1)] + . $nouns[random_int(0, count($nouns)-1)]; + // append random digits to fulfill length + $digitsNeeded = max(0, $available - strlen($part)); + $suffix = substr($part . self::randomString($digitsNeeded, self::$sets['digits']), 0, $available); + return $prefix === '' ? $suffix : ($prefix . $sep . $suffix); + } + + // Generate URI-safe slug: groups count and each group's length + public static function generateUriSlug(int $groups = 3, int $groupLength = 6, string $sep = '-'): string + { + if ($groups <= 0 || $groupLength <= 0) return ''; + $chars = strtolower(self::$sets['lower'] . self::$sets['digits']); + $parts = []; + for ($g = 0; $g < $groups; $g++) { + $parts[] = self::randomString($groupLength, $chars); + } + return implode($sep, $parts); + } + + // Generate password with options: ensureMixed ensures at least one char from each requested set + public static function generatePassword(int $length = 16, bool $ensureMixed = true, array $includeSets = ['upper','lower','digits','special']): string + { + if ($length <= 0) return ''; + + // build charset + $charset = ''; + $validSets = []; + foreach ($includeSets as $s) { + if (isset(self::$sets[$s])) { + $charset .= self::$sets[$s]; + $validSets[] = $s; + } + } + if ($charset === '') { + $charset = self::$sets['lower'] . self::$sets['digits']; + $validSets = ['lower', 'digits']; + } + + if (!$ensureMixed || count($validSets) === 1) { + return self::randomString($length, $charset); + } + + // Ensure at least one char from each selected set + $passwordChars = []; + foreach ($validSets as $s) { + $passwordChars[] = self::randomChar(self::$sets[$s]); + } + + // Fill remaining + $remaining = $length - count($passwordChars); + for ($i = 0; $i < $remaining; $i++) { + $passwordChars[] = self::randomChar($charset); + } + + // Shuffle securely + $shuffled = []; + $len = count($passwordChars); + while ($len) { + $idx = random_int(0, $len - 1); + $shuffled[] = $passwordChars[$idx]; + array_splice($passwordChars, $idx, 1); + $len--; + } + return implode('', $shuffled); + } + + // Generate API version like XXXXX-XXXXX-XXXXX-XXXXX-XXXXX (uppercase letters and digits) + public static function generateApiVer(int $groups = 5, int $groupLength = 5, string $sep = '-'): string + { + if ($groups <= 0 || $groupLength <= 0) return ''; + $chars = self::$sets['upper'] . self::$sets['digits']; + $parts = []; + for ($g = 0; $g < $groups; $g++) { + $parts[] = strtoupper(self::randomString($groupLength, $chars)); + } + return implode($sep, $parts); + } + + // Convenience: generate RFC4122 v4 UUID + public static function generateUuidV4(): string + { + $data = random_bytes(16); + // set version to 0100 + $data[6] = chr((ord($data[6]) & 0x0f) | 0x40); + // set bits 6-7 to 10 + $data[8] = chr((ord($data[8]) & 0x3f) | 0x80); + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); + } +} + +?> \ No newline at end of file diff --git a/v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php b/v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php new file mode 100644 index 0000000..0b3f884 --- /dev/null +++ b/v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php b/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php new file mode 100644 index 0000000..c122a6b --- /dev/null +++ b/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php.bak b/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php.bak new file mode 100644 index 0000000..e69de29 diff --git a/v.0.4/SilverSoft.ValidateTest.UniversalKeyGenerator.php b/v.0.4/SilverSoft.ValidateTest.UniversalKeyGenerator.php new file mode 100644 index 0000000..614e29c --- /dev/null +++ b/v.0.4/SilverSoft.ValidateTest.UniversalKeyGenerator.php @@ -0,0 +1,22 @@ +generateApiKey() . "\n"; + echo "Username: " . $generator->generateUsername() . "\n"; + echo "Upload URI: " . $generator->generateUploadUri() . "\n"; + echo "Password: " . $generator->generateUserPassword() . "\n"; + echo "Product Key: " . $generator->generateProductKey() . "\n\n"; + + echo "=== SEQUENTIAL GENERATION ===\n"; + $apiKey = $generator->generateApiKey(); + echo "Current API Key: $apiKey\n"; + echo "Next API Key: " . $generator->nextApiKey($apiKey) . "\n"; + echo "Previous API Key: " . $generator->previousApiKey() . "\n\n"; + + $productKey = $generator->generateProductKey(); + echo "Current Product Key: $productKey\n"; + echo "Next Product Key: " . $generator->nextProductKey($productKey) . "\n"; + echo "Previous Product Key: " . $generator->previousProductKey() . "\n"; +?> \ No newline at end of file From b47bca8e053c45c2b2b6af8a587b1ba8e7e17e1d Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:01:15 +0100 Subject: [PATCH 61/72] Collection of Universal Generators Finally Back on Track and Almost Ready to Use Them --- ...ft.ValidateTest.UniversalGenerator.php.bak | 0 v.0.4/UniversalGenerator.php | 107 ++++++++++++++++++ 2 files changed, 107 insertions(+) delete mode 100644 v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php.bak create mode 100644 v.0.4/UniversalGenerator.php diff --git a/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php.bak b/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php.bak deleted file mode 100644 index e69de29..0000000 diff --git a/v.0.4/UniversalGenerator.php b/v.0.4/UniversalGenerator.php new file mode 100644 index 0000000..1c7493a --- /dev/null +++ b/v.0.4/UniversalGenerator.php @@ -0,0 +1,107 @@ += 0"); + } + $chars = []; + $v = $index; + while ($v > 0) { + $rem = $v % 26; + $chars[] = chr(65 + $rem); + $v = intdiv($v, 26); + } + while (count($chars) < $length) { + $chars[] = 'A'; + } + $chars = array_reverse($chars); + $s = implode('', array_slice($chars, -1 * $length)); + return $s; + } + + // ApiKey: random or deterministic by index + public static function apiKey(?int $index = null, int $length = 8): string + { + return $index === null ? self::randomUpper($length) : self::fromIndexUpper($index, $length); + } + + // UserName: same pattern as ApiKey (capitals) + public static function userName(?int $index = null, int $length = 8): string + { + return self::apiKey($index, $length); + } + + // UploadUri: returns a path-friendly token (caps) optionally prefixed + public static function uploadUri(?int $index = null, int $length = 8, string $prefix = '/upload/'): string + { + $token = $index === null ? self::randomUpper($length) : self::fromIndexUpper($index, $length); + return rtrim($prefix, '/') . '/' . $token; + } + + // Random password: letters (upper+lower) and digits, max length 16 + public static function password(int $length = 16, bool $includeDigits = true): string + { + if ($length < 1) throw new InvalidArgumentException("Length must be >= 1"); + if ($length > 16) $length = 16; + $chars = array_merge( + range('a', 'z'), + range('A', 'Z'), + $includeDigits ? range('0','9') : [] + ); + $out = ''; + $max = count($chars) - 1; + for ($i = 0; $i < $length; $i++) { + $out .= $chars[random_int(0, $max)]; + } + return $out; + } + + // ProductKey: deterministic from index or random; format groups e.g. 5 groups of 5 capitals + public static function productKey(?int $index = null, int $groups = 5, int $groupLen = 5): string + { + $total = $groups * $groupLen; + if ($index === null) { + // random version + $s = self::randomUpper($total); + } else { + // deterministic: expand index across total length + $s = self::fromIndexUpper($index, $total); + } + $parts = []; + for ($i = 0; $i < $groups; $i++) { + $parts[] = substr($s, $i * $groupLen, $groupLen); + } + return implode('-', $parts); + } + + // Next index + public static function nextIndex(int $index): int + { + if ($index < 0) throw new InvalidArgumentException("Index must be >= 0"); + return $index + 1; + } + + // Previous index (returns null when no previous) + public static function previousIndex(int $index): ?int + { + if ($index <= 0) return null; + return $index - 1; + } +} + +?> \ No newline at end of file From df2a482de534dd1739a6c9e75a374178c8a402fb Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Fri, 5 Dec 2025 14:43:59 +0100 Subject: [PATCH 62/72] Just a Little Update of Renaming Renaming Files and Updating Source Code to make it working. --- ...erSoft.RunCommand.ComplexKeyGenerator.php} | 0 ...verSoft.RunCommand.UniversalGenerator.php} | 0 ...Soft.RunCommand.UniversalKeyGenerator.php} | 0 ...rSoft.ValidateTest.ComplexKeyGenerator.php | 26 ++++++++++++++++- ...erSoft.ValidateTest.UniversalGenerator.php | 2 +- ...oft.ValidateTest.UniversalKeyGenerator.php | 28 +++++++++++++++++-- 6 files changed, 51 insertions(+), 5 deletions(-) rename v.0.4/{ComplexKeyGenerator.php => SilverSoft.RunCommand.ComplexKeyGenerator.php} (100%) rename v.0.4/{UniversalGenerator.php => SilverSoft.RunCommand.UniversalGenerator.php} (100%) rename v.0.4/{UniversalKeyGenerator.php => SilverSoft.RunCommand.UniversalKeyGenerator.php} (100%) diff --git a/v.0.4/ComplexKeyGenerator.php b/v.0.4/SilverSoft.RunCommand.ComplexKeyGenerator.php similarity index 100% rename from v.0.4/ComplexKeyGenerator.php rename to v.0.4/SilverSoft.RunCommand.ComplexKeyGenerator.php diff --git a/v.0.4/UniversalGenerator.php b/v.0.4/SilverSoft.RunCommand.UniversalGenerator.php similarity index 100% rename from v.0.4/UniversalGenerator.php rename to v.0.4/SilverSoft.RunCommand.UniversalGenerator.php diff --git a/v.0.4/UniversalKeyGenerator.php b/v.0.4/SilverSoft.RunCommand.UniversalKeyGenerator.php similarity index 100% rename from v.0.4/UniversalKeyGenerator.php rename to v.0.4/SilverSoft.RunCommand.UniversalKeyGenerator.php diff --git a/v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php b/v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php index 0b3f884..b0d7ebd 100644 --- a/v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php +++ b/v.0.4/SilverSoft.ValidateTest.ComplexKeyGenerator.php @@ -1,10 +1,11 @@ \ No newline at end of file diff --git a/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php b/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php index c122a6b..7c65be0 100644 --- a/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php +++ b/v.0.4/SilverSoft.ValidateTest.UniversalGenerator.php @@ -1,5 +1,5 @@ generateApiKey() . "\n"; + echo "Username: " . $generator->generateUsername() . "\n"; + echo "Upload URI: " . $generator->generateUploadUri() . "\n"; + echo "Password: " . $generator->generateUserPassword() . "\n"; + echo "Product Key: " . $generator->generateProductKey() . "\n\n"; + + echo "=== SEQUENTIAL GENERATION ===\n"; + $apiKey = $generator->generateApiKey(); + echo "Current API Key: $apiKey\n"; + echo "Next API Key: " . $generator->nextApiKey($apiKey) . "\n"; + echo "Previous API Key: " . $generator->previousApiKey() . "\n\n"; + + $productKey = $generator->generateProductKey(); + echo "Current Product Key: $productKey\n"; + echo "Next Product Key: " . $generator->nextProductKey($productKey) . "\n"; + echo "Previous Product Key: " . $generator->previousProductKey() . "\n"; +} else { + $generator = new UniversalKeyGenerator(); echo "=== RANDOM GENERATION ===\n"; echo "API Key: " . $generator->generateApiKey() . "\n"; echo "Username: " . $generator->generateUsername() . "\n"; @@ -19,4 +40,5 @@ echo "Current Product Key: $productKey\n"; echo "Next Product Key: " . $generator->nextProductKey($productKey) . "\n"; echo "Previous Product Key: " . $generator->previousProductKey() . "\n"; +} ?> \ No newline at end of file From 7f33976adcccc6ad3edd7c92eb260de8bfc5f562 Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sat, 10 Jan 2026 12:23:17 +0100 Subject: [PATCH 63/72] Update Before Joining The Foundation CANG To Master Up --- ...lex_Alpha-Numeric_Generator.code-workspace | 8 + v.0.1/SilverSoft.RunExample.php | 65 ++++ v.0.1/examplo.php | 30 -- v.0.2/SilverSoft.Unique_Key_Generator.php | 148 +++++++++ v.0.2/unique_key_generator.php | 305 ++++++++++-------- v.0.5.FinallVersion/Base_CANG_CommandAI.md | 105 ++++++ .../CANG_LanguageCharFoundation.php | 43 +++ v.0.5.FinallVersion/Base_CANG_Display.php | 0 .../Base_CANG_Generators/CANG.php | 175 ++++++++++ .../Base_CANG_Generators/CANG_Benchmark.php | 85 +++++ .../Base_CANG_Generators/CANG_MS_G.php | 0 .../Base_CANG_Generators/CANG_Test.php | 119 +++++++ .../CANG_LanguageCharClass.php | 28 ++ .../Base_CANG_Language/CANG_LanguageClass.php | 151 +++++++++ .../Base_CANG_Language/CANG_LanguageCode.php | 88 +++++ .../Example_Generate_ID.php | 8 + .../Example_Generate_ID_JSON.php | 9 + .../Example_Generate_Random.php | 8 + .../Example_Generate_Random_JSON.php | 9 + .../Example_Generate_String.php | 11 + .../Example_Generate_String_JSON.php | 12 + .../Example_Microsoft_SN_Generate_ID.php | 6 + .../Example_Microsoft_SN_Generate_ID_JSON.php | 7 + .../Example_Microsoft_SN_Generate_Random.php | 6 + ...mple_Microsoft_SN_Generate_Random_JSON.php | 7 + 25 files changed, 1262 insertions(+), 171 deletions(-) create mode 100644 Complex_Alpha-Numeric_Generator.code-workspace create mode 100644 v.0.1/SilverSoft.RunExample.php delete mode 100644 v.0.1/examplo.php create mode 100644 v.0.2/SilverSoft.Unique_Key_Generator.php create mode 100644 v.0.5.FinallVersion/Base_CANG_CommandAI.md create mode 100644 v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageCharFoundation.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Display.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Generators/CANG.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Generators/CANG_MS_G.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php create mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String_JSON.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php create mode 100644 v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php diff --git a/Complex_Alpha-Numeric_Generator.code-workspace b/Complex_Alpha-Numeric_Generator.code-workspace new file mode 100644 index 0000000..876a149 --- /dev/null +++ b/Complex_Alpha-Numeric_Generator.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": {} +} \ No newline at end of file diff --git a/v.0.1/SilverSoft.RunExample.php b/v.0.1/SilverSoft.RunExample.php new file mode 100644 index 0000000..bc3002a --- /dev/null +++ b/v.0.1/SilverSoft.RunExample.php @@ -0,0 +1,65 @@ +' . htmlspecialchars($msg, ENT_QUOTES | ENT_SUBSTITUTE) . '

'; + } + exit(1); +} + +// Get next number (safe call) +$nextNumber = anderson_makiyama_get_next_alphanumeric($currentNumber); + +// Prepare output mode +$isWeb = PHP_SAPI !== 'cli'; +$lineSep = $isWeb ? '
' : PHP_EOL; + +// Print header (small HTML wrapper for browser) +if ($isWeb) { + echo 'Alphanumeric generator'; + echo '

Single step

'; + echo '
Current = ' . htmlspecialchars($currentNumber, ENT_QUOTES | ENT_SUBSTITUTE) . '
'; + echo '
Next = ' . htmlspecialchars($nextNumber, ENT_QUOTES | ENT_SUBSTITUTE) . '
'; + echo '
'; +} else { + echo "Current = {$currentNumber}{$lineSep}"; + echo "Next = {$nextNumber}{$lineSep}"; + echo str_repeat('-', 40) . $lineSep; +} + +// Generate many sequential codes (buffered for performance) +$count = 5000; +$maxAllowed = 100000; // safety cap +if ($count > $maxAllowed) { + $count = $maxAllowed; +} + +$code = $currentNumber; +$lines = []; +$start = microtime(true); +for ($i = 0; $i < $count; $i++) { + // If generator can throw, consider wrapping this call in try/catch + $code = anderson_makiyama_get_next_alphanumeric($code); + $lines[] = $isWeb ? htmlspecialchars($code, ENT_QUOTES | ENT_SUBSTITUTE) : $code; +} +$elapsed = microtime(true) - $start; + +// Output buffered results +if ($isWeb) { + echo '

A lot of sequential alphanumeric strings

'; + echo implode('
', $lines); + echo '
'; + echo '
Generated ' . count($lines) . ' items in ' . number_format($elapsed, 4) . 's'; +} else { + echo "Generated " . count($lines) . " items in " . number_format($elapsed, 4) . "s{$lineSep}"; + echo implode($lineSep, $lines) . $lineSep; +} diff --git a/v.0.1/examplo.php b/v.0.1/examplo.php deleted file mode 100644 index 2c3ecd4..0000000 --- a/v.0.1/examplo.php +++ /dev/null @@ -1,30 +0,0 @@ -A lot of sequential alphanumeric strings
"; - -$code = $current_number; - -for($i=0;$i<5000;$i++){ - - $code = anderson_makiyama_get_next_alphanumeric($code); - - echo $code; echo "
"; - -} - - -?> diff --git a/v.0.2/SilverSoft.Unique_Key_Generator.php b/v.0.2/SilverSoft.Unique_Key_Generator.php new file mode 100644 index 0000000..ab9e339 --- /dev/null +++ b/v.0.2/SilverSoft.Unique_Key_Generator.php @@ -0,0 +1,148 @@ + Time stamp +$code_time = time(); +//Informace o tom kolik druhu klicu muze funkce poskytnout +$code_max_type = 5; +//Druhy klicu +if ($default_code_type==1){ +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('a','z')); +//Jmeno generovaneho klice +$code_name = '[A-Z,a-z]'; +//Cislo generovaneho klice +$code_number = 1; +} +if ($default_code_type==2){ +//Megaupload.com style +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('0','9')); +//Jmeno generovaneho klice +$code_name = '[A-Z,0-9]'; +//Cislo generovaneho klice +$code_number = 2; +} +if ($default_code_type==3){ +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('a','z'), range('0','9')); +//Jmeno generovaneho klice +$code_name = '[a-z,0-9]'; +//Cislo generovaneho klice +$code_number = 3; +} +if ($default_code_type==4){ +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('a','z'), range('0','9')); +//Jmeno generovaneho klice +$code_name = '[A-Z,a-z,0-9]'; +//Cislo generovaneho klice +$code_number = 4; +} +if ($default_code_type>4){ +//Youtube.com style +//Sestaveni array tabulky s jednotlivimy znaky +$characters = array_merge(range('A','Z'), range('a','z'), range('0','9'),array('-','_')); +//Jmeno generovaneho klice +$code_name = '[A-Z,a-z,0-9,-_]'; +//Cislo generovaneho klice +$code_number = 5; +} +//Vypocet kolik klicu muze generator poskytnout +$count_characters = count($characters); +$count_range = pow($count_characters, $default_code_length); +//Oznaceni konce ve vypoctu klicu +$character_end = 'Z'; +$character_start = ''; +$array_chars = array_flip($characters); +//Podminka slouzi pro detekci jestly ma funkce vygenerovat pocatecni ,nahodny nebo nasledujici klic + if ($default_code==false){ +//Generator nahodneho nebo pocatecniho klice +for ($n=1;$default_code_length>=$n;$n++){ +if ($code_random){ +//Generace nahodneho klice +$character_start .= $characters[rand(0,($count_characters-1))]; +}else{ +//Generace pocatecniho klice +$character_start .= 'A'; +} +} +$code_base = $character_start; + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_time'=>$code_time,'code_count'=>code_count($code_base,$array_chars),'code_range'=>$count_range,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +}else{ +//Generace nasledujiciho klice + $chars = $characters; + $code_array = str_split($default_code); + // Starts searching for the next character capable of increasing, or different from Z + // Note that initiates the last character to the first + for($i = count($code_array)-1;$i>-1;$i--){ + if($code_array[$i] == $character_end){ + if($i=='0'){ + //If equal to Z and is the first character, mental increases the length and zeroes + $code_array = array_fill(0,count($code_array) + 1,0); +$code_base = implode("",$code_array); +//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu +if ($default_code_length==strlen($code_base)){ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }else{ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +} + }else{ + if($code_array[$i -1] != $character_end){ + // If the character is different from previous Z, increment it and resets the current and subsequent + // If the character is above the first, also works because it increases and the other resets + $code_array[$i -1] = $chars[array_search($code_array[$i -1],$chars) + 1]; + for($j = $i; $j < count($code_array); $j++){ + $code_array[$j] = '0'; + } +$code_base = implode("",$code_array); +//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu +if ($default_code_length==strlen($code_base)){ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }else{ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +} + } + } + + }else{ + // calculate the next character, or increments the current + $code_array[$i] = $chars[array_search($code_array[$i],$chars) + 1]; + if($i == '0'){ + // If the first character, meaning others Salo z + // That is, they reset + $novo_array = array_fill(0,count($code_array),0); + $novo_array[0] = $code_array[$i]; + $code_array = $novo_array; + } +$code_base = implode("",$code_array); +//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu +if ($default_code_length==strlen($code_base)){ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); + }else{ + return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); +} + } + } +} + +} +?> diff --git a/v.0.2/unique_key_generator.php b/v.0.2/unique_key_generator.php index ab9e339..9647725 100644 --- a/v.0.2/unique_key_generator.php +++ b/v.0.2/unique_key_generator.php @@ -1,148 +1,171 @@ length = max(1, $length); + $this->type = min(max(1, $type), $this->maxType); + $this->chars = $this->buildCharset($this->type); + $this->indexMap = array_flip($this->chars); + } + + private function buildCharset(int $type): array + { + return match ($type) { + self::TYPE_ALPHA_UPPER_NUM => array_merge(range('A', 'Z'), range('0', '9')), + self::TYPE_ALPHA_LOWER_NUM => array_merge(range('a', 'z'), range('0', '9')), + self::TYPE_ALPHA_NUM => array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9')), + self::TYPE_URLSAFE => array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'), ['-', '_']), + default => array_merge(range('A', 'Z'), range('a', 'z')), + }; + } + + /** + * Generate a random (or deterministic all-first) code. + */ + public function generateRandom(bool $secure = true, bool $useFirstChar = false): string + { + $out = ''; + $max = count($this->chars) - 1; + for ($i = 0; $i < $this->length; $i++) { + if ($useFirstChar) { + $out .= $this->chars[0]; + continue; + } + $idx = $secure ? random_int(0, $max) : mt_rand(0, $max); + $out .= $this->chars[$idx]; } - return $number; # pokud chceš tak ještě +1 -} -//Casovy otisk -> Time stamp -$code_time = time(); -//Informace o tom kolik druhu klicu muze funkce poskytnout -$code_max_type = 5; -//Druhy klicu -if ($default_code_type==1){ -//Sestaveni array tabulky s jednotlivimy znaky -$characters = array_merge(range('A','Z'), range('a','z')); -//Jmeno generovaneho klice -$code_name = '[A-Z,a-z]'; -//Cislo generovaneho klice -$code_number = 1; -} -if ($default_code_type==2){ -//Megaupload.com style -//Sestaveni array tabulky s jednotlivimy znaky -$characters = array_merge(range('A','Z'), range('0','9')); -//Jmeno generovaneho klice -$code_name = '[A-Z,0-9]'; -//Cislo generovaneho klice -$code_number = 2; -} -if ($default_code_type==3){ -//Sestaveni array tabulky s jednotlivimy znaky -$characters = array_merge(range('a','z'), range('0','9')); -//Jmeno generovaneho klice -$code_name = '[a-z,0-9]'; -//Cislo generovaneho klice -$code_number = 3; -} -if ($default_code_type==4){ -//Sestaveni array tabulky s jednotlivimy znaky -$characters = array_merge(range('A','Z'), range('a','z'), range('0','9')); -//Jmeno generovaneho klice -$code_name = '[A-Z,a-z,0-9]'; -//Cislo generovaneho klice -$code_number = 4; -} -if ($default_code_type>4){ -//Youtube.com style -//Sestaveni array tabulky s jednotlivimy znaky -$characters = array_merge(range('A','Z'), range('a','z'), range('0','9'),array('-','_')); -//Jmeno generovaneho klice -$code_name = '[A-Z,a-z,0-9,-_]'; -//Cislo generovaneho klice -$code_number = 5; -} -//Vypocet kolik klicu muze generator poskytnout -$count_characters = count($characters); -$count_range = pow($count_characters, $default_code_length); -//Oznaceni konce ve vypoctu klicu -$character_end = 'Z'; -$character_start = ''; -$array_chars = array_flip($characters); -//Podminka slouzi pro detekci jestly ma funkce vygenerovat pocatecni ,nahodny nebo nasledujici klic - if ($default_code==false){ -//Generator nahodneho nebo pocatecniho klice -for ($n=1;$default_code_length>=$n;$n++){ -if ($code_random){ -//Generace nahodneho klice -$character_start .= $characters[rand(0,($count_characters-1))]; -}else{ -//Generace pocatecniho klice -$character_start .= 'A'; -} -} -$code_base = $character_start; - return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_time'=>$code_time,'code_count'=>code_count($code_base,$array_chars),'code_range'=>$count_range,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); -}else{ -//Generace nasledujiciho klice - $chars = $characters; - $code_array = str_split($default_code); - // Starts searching for the next character capable of increasing, or different from Z - // Note that initiates the last character to the first - for($i = count($code_array)-1;$i>-1;$i--){ - if($code_array[$i] == $character_end){ - if($i=='0'){ - //If equal to Z and is the first character, mental increases the length and zeroes - $code_array = array_fill(0,count($code_array) + 1,0); -$code_base = implode("",$code_array); -//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu -if ($default_code_length==strlen($code_base)){ - return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); - }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); - }else{ - return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); -} - }else{ - if($code_array[$i -1] != $character_end){ - // If the character is different from previous Z, increment it and resets the current and subsequent - // If the character is above the first, also works because it increases and the other resets - $code_array[$i -1] = $chars[array_search($code_array[$i -1],$chars) + 1]; - for($j = $i; $j < count($code_array); $j++){ - $code_array[$j] = '0'; - } -$code_base = implode("",$code_array); -//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu -if ($default_code_length==strlen($code_base)){ - return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); - }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); - }else{ - return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); -} - } + return $out; + } + + /** + * Generate next code in sequence. Returns associative payload similar to original. + * Throws InvalidArgumentException on invalid input. + */ + public function next(string $current): array + { + $time = time(); + if ($current === '') { + throw new InvalidArgumentException('Current code must be non-empty.'); + } + + // validate characters + $charsCount = count($this->chars); + $currentArr = preg_split('//u', $current, -1, PREG_SPLIT_NO_EMPTY); + foreach ($currentArr as $ch) { + if (!isset($this->indexMap[$ch])) { + throw new InvalidArgumentException('Current code contains invalid character: ' . $ch); + } + } + + // convert to indices + $indices = array_map(fn($c) => $this->indexMap[$c], $currentArr); + + // increment with carry + $pos = count($indices) - 1; + $carry = 1; + while ($pos >= 0 && $carry) { + $indices[$pos] += $carry; + if ($indices[$pos] >= $charsCount) { + $indices[$pos] = 0; + $carry = 1; + $pos--; + } else { + $carry = 0; } - - }else{ - // calculate the next character, or increments the current - $code_array[$i] = $chars[array_search($code_array[$i],$chars) + 1]; - if($i == '0'){ - // If the first character, meaning others Salo z - // That is, they reset - $novo_array = array_fill(0,count($code_array),0); - $novo_array[0] = $code_array[$i]; - $code_array = $novo_array; - } -$code_base = implode("",$code_array); -//Podminka hlida generaci spravneho klice, pokud je klic spravne dostanete -> 'code_message'=>'' jinak je vygenerovany klic spatne nebo uz funkce vygenerovala maximalni pocet klicu -if ($default_code_length==strlen($code_base)){ - return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); - }elseif($default_code_length$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_upper_or_full','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); - }else{ - return array('code_base'=>$code_base,'code_base_md5'=>md5($code_base),'code_base_sha1'=>sha1($code_base),'code_base64_encode'=>base64_encode($code_base),'code_range'=>$count_range,'code_count'=>code_count($code_base,$array_chars),'code_time'=>$code_time,'code_message'=>'is_lower','code_name'=>$code_name,'code_type'=>$code_number,'code_max_type'=>$code_max_type,'code_length'=>$default_code_length); -} } + + if ($carry === 1) { + // overflow: increase length by 1 (consistent with original behaviour) + array_unshift($indices, 0); + } + + // build code from indices + $newChars = array_map(fn($i) => $this->chars[$i], $indices); + $codeBase = implode('', $newChars); + + // compute simple base-n count (may overflow native ints for huge lengths) + $countNumber = $this->baseNToInteger($indices, $charsCount); + + // prepare payload (single place) + return [ + 'code_base' => $codeBase, + 'code_base_md5' => md5($codeBase), + 'code_base_sha1' => sha1($codeBase), + 'code_base64_encode' => base64_encode($codeBase), + 'code_time' => $time, + 'code_count' => $countNumber, + 'code_range' => $this->safePowString($charsCount, $this->length), + 'code_message' => (strlen($codeBase) > $this->length) ? 'is_upper_or_full' : '', + 'code_name' => $this->charsetName(), + 'code_type' => $this->type, + 'code_max_type' => $this->maxType, + 'code_length' => $this->length, + ]; + } + + private function charsetName(): string + { + return match ($this->type) { + self::TYPE_ALPHA_UPPER_NUM => '[A-Z,0-9]', + self::TYPE_ALPHA_LOWER_NUM => '[a-z,0-9]', + self::TYPE_ALPHA_NUM => '[A-Z,a-z,0-9]', + self::TYPE_URLSAFE => '[A-Z,a-z,0-9,-_]', + default => '[A-Z,a-z]', + }; + } + + /** + * Convert base-n digits to integer (may return string if large). + */ + private function baseNToInteger(array $digits, int $base) + { + // prefer BCMath for exact big integers when available + if (function_exists('bcadd')) { + $acc = '0'; + foreach ($digits as $d) { + $acc = bcmul($acc, (string)$base); + $acc = bcadd($acc, (string)$d); + } + return $acc; + } + + // fallback to native integer (may overflow) + $acc = 0; + foreach ($digits as $d) { + $acc = $acc * $base + $d; + } + return $acc; + } + + private function safePowString(int $base, int $exp): string + { + if (function_exists('bcpow')) { + return bcpow((string)$base, (string)$exp); + } + // fallback (may be float and imprecise for large exp) + return (string) pow($base, $exp); } } - -} + +// Example usage: +$g = new UniqueKeyGenerator(8, 5); +$random = $g->generateRandom(); +$nextInfo = $g->next('aZ5sTp53x'); +var_dump($random, $nextInfo); + ?> diff --git a/v.0.5.FinallVersion/Base_CANG_CommandAI.md b/v.0.5.FinallVersion/Base_CANG_CommandAI.md new file mode 100644 index 0000000..8bdd3fc --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_CommandAI.md @@ -0,0 +1,105 @@ +Create PHP Code: + +Name: CANG_LanguageCharFoundation + +Fundamental Config File: + +Set The Fundamental Language Characters: +LanguageChar : Upper -> range('A','Z') +LanguageChar : Lower -> range('a','z') +LanguageChar : Numeric -> range('0','9') +LanguageChar : ShortSpecial -> str_split('_-') +LanguageChar : FullSpecial -> str_split('#$%&+-@_') + +Create PHP Class: + +Name: CANG_LanguageCharClass + +Set The Basic Language Name: +LanguageName : Alphabet_Upper +LanguageName : Alphabet_Lower +LanguageName : Alphabet_Mix +LanguageName : Numeric +LanguageName : Alphabet_Upper_Num +LanguageName : Alphabet_Lower_Num +LanguageName : Alphabet_Mix_Num +LanguageName : Alphabet_Mix_Num_SpecialShort +LanguageName : Alphabet_Mix_Num_SpecialFull + +Set The Basic Language Type: +LanguageType : '[A-Z]' +LanguageType : '[a-z]' +LanguageType : '[A-Z,a-z]' +LanguageType : '[0-9]' +LanguageType : '[A-Z,0-9]' +LanguageType : '[a-z,0-9]' +LanguageType : '[A-Z,a-z,0-9]' +LanguageType : '[A-Z,a-z,0-9,-_]' +LanguageType : '[A-Z,a-z,0-9,-_]' + +Set The Basic Language Description: +LanguageDescription : 'Alphabetical -> Simple: Capital letters' +LanguageDescription : 'Alphabetical -> Simple: Small letters' +LanguageDescription : 'Alphabetical -> Mix: Capital and Small letters' +LanguageDescription : 'Numerical -> Simple' +LanguageDescription : 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)' +LanguageDescription : 'Alphabetical and Numerical -> Simple: Small letters' +LanguageDescription : 'Alphabetical and Numerical -> Mix: Capital and Small letters' +LanguageDescription : 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)' +LanguageDescription : 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' + +Set The Basic Language Range: +LanguageRange : LanguageChar[Upper] +LanguageRange : LanguageChar[Lower] +LanguageRange : LanguageChar[Upper], LanguageChar[Lower] +LanguageRange : LanguageChar[Numeric] +LanguageRange : LanguageChar[Upper], LanguageChar[Numeric] +LanguageRange : LanguageChar[Lower], LanguageChar[Numeric] +LanguageRange : LanguageChar[Upper], LanguageChar[Lower], LanguageChar[Numeric] +LanguageRange : LanguageChar[Upper], LanguageChar[Lower], LanguageChar[Numeric], LanguageChar[ShortSpecial] +LanguageRange : LanguageChar[Upper], LanguageChar[Lower], LanguageChar[Numeric], LanguageChar[FullSpecial] + +Set The Basic Language Id: +LanguageId : 1 +LanguageId : 2 +LanguageId : 3 +LanguageId : 4 +LanguageId : 5 +LanguageId : 6 +LanguageId : 7 +LanguageId : 8 +LanguageId : 9 + +Set The Basic Language Order: +LanguageOrder : LanguageId, LanguageName, LanguageType, LanguageDescription, LanguageRange + +Set The Basic Language Definition: +LanguageDefinition -> LanguageOrder + +Name: Complex Alpha Numeric Generator (CANG) + +Create PHP CANG Class: + +Able To Select Language: +LanguageDefinition + +Able To Change Length: +Minimum Length = 8 + +Able To Select Generation Mode: +GenerateMode : Beginning, Current, Next, Previous, End, Random, Id + +Example Mode Selection: +Mode : Beginning(:NoInPut:) +Mode : Current(:InPutString:) +Mode : Next(:InPutString:) +Mode : Previous(:InPutString:) +Mode : End(:NoInPut:) +Mode : Random(:NoInPut:) +Mode : Id(:InPutNumber:) + +Able To Read Position: +Example: +AAAAAAAA = 0 +AAAAAAAB = 1 +AAAAAAAC = 2 diff --git a/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageCharFoundation.php b/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageCharFoundation.php new file mode 100644 index 0000000..ae57b25 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageCharFoundation.php @@ -0,0 +1,43 @@ + [ + + // A–Z + 'Upper' => range('A', 'Z'), + + // a–z + 'Lower' => range('a', 'z'), + + // 0–9 + 'Numeric' => range('0', '9'), + + // Minimal special characters + 'ShortSpecial' => str_split('_-'), + + // Full special character set + 'FullSpecial' => str_split('#$%&+-@_'), + ], + +]; + +/* +Example: How To Use + +$LanguageCharFoundation = require __DIR__ . '/CANG_Config/CANG_LanguageCharFoundation.php'; + +Then Insert This Code Into Process: +$LanguageCharFoundation['LanguageChar'] +It Will Help You To Match The Configuration InSide The Array. +*/ + +?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Display.php b/v.0.5.FinallVersion/Base_CANG_Display.php new file mode 100644 index 0000000..e69de29 diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG.php b/v.0.5.FinallVersion/Base_CANG_Generators/CANG.php new file mode 100644 index 0000000..376f5c4 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Generators/CANG.php @@ -0,0 +1,175 @@ +setLanguage($languageDefinition); + $this->setLength($length); + } + + // --------------------------------------------------------- + // LANGUAGE + LENGTH + // --------------------------------------------------------- + + public function setLanguage(array $languageDefinition): void + { + if (empty($languageDefinition)) { + throw new InvalidArgumentException("Language definition cannot be empty."); + } + + $this->language = array_values($languageDefinition); + } + + public function setLength(int $length): void + { + if ($length < 8) { + throw new InvalidArgumentException("Minimum length is 8."); + } + $this->length = $length; + } + + // --------------------------------------------------------- + // CORE: POSITION → STRING + // --------------------------------------------------------- + + public function positionToString(int $position): string + { + if ($position < 0) { + throw new InvalidArgumentException("Position cannot be negative."); + } + + $base = count($this->language); + $result = ''; + + while ($position >= 0) { + $result = $this->language[$position % $base] . $result; + $position = intdiv($position, $base) - 1; + } + + return str_pad($result, $this->length, $this->language[0], STR_PAD_LEFT); + } + + // --------------------------------------------------------- + // CORE: STRING → POSITION + // --------------------------------------------------------- + + public function stringToPosition(string $string): int + { + if (strlen($string) !== $this->length) { + throw new InvalidArgumentException("Input string must be exactly {$this->length} characters."); + } + + $base = count($this->language); + $chars = str_split($string); + $position = 0; + + foreach ($chars as $char) { + $index = array_search($char, $this->language, true); + if ($index === false) { + throw new InvalidArgumentException("Invalid character '$char' in input."); + } + $position = $position * $base + ($index + 1); + } + + return $position - 1; + } + + // --------------------------------------------------------- + // GENERATION MODES + // --------------------------------------------------------- + + public function generate(string $mode, ?string $current = null): string + { + switch ($mode) { + + case self::MODE_BEGINNING: + return str_repeat($this->language[0], $this->length); + + case self::MODE_END: + return str_repeat(end($this->language), $this->length); + + case self::MODE_RANDOM: + return $this->randomString(); + + case self::MODE_CURRENT: + if ($current === null) { + throw new InvalidArgumentException("Current mode requires input string."); + } + return $current; + + case self::MODE_NEXT: + if ($current === null) { + throw new InvalidArgumentException("Next mode requires input string."); + } + return $this->positionToString($this->stringToPosition($current) + 1); + + case self::MODE_PREVIOUS: + if ($current === null) { + throw new InvalidArgumentException("Previous mode requires input string."); + } + return $this->positionToString( + max(0, $this->stringToPosition($current) - 1) + ); + + case self::MODE_ID: + if ($current === null || !ctype_digit((string)$current)) { + throw new InvalidArgumentException("Id mode requires a numeric input."); + } + return $this->positionToString((int)$current); + + default: + throw new InvalidArgumentException("Unknown mode '$mode'."); + } + } + + // --------------------------------------------------------- + // RANDOM GENERATOR + // --------------------------------------------------------- + + protected function randomString(): string + { + $result = ''; + $max = count($this->language) - 1; + + for ($i = 0; $i < $this->length; $i++) { + $result .= $this->language[random_int(0, $max)]; + } + + return $result; + } +} +/* +Example: How To Use + +$language = range('A', 'Z'); +$CANG = New CANG($language, 8); + +echo $CANG->generate(CANG::MODE_BEGINNING); // AAAAAAAA +echo $CANG->generate(CANG::MODE_ID, "0"); // AAAAAAAA +echo $CANG->generate(CANG::MODE_ID, "1"); // AAAAAAAB +echo $CANG->generate(CANG::MODE_ID, "2"); // AAAAAAAC + +echo $CANG->generate(CANG::MODE_NEXT, "AAAAAAAB"); // AAAAAAAC +echo $CANG->stringToPosition("AAAAAAAC"); // 2 +*/ +?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php b/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php new file mode 100644 index 0000000..7278ef1 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php @@ -0,0 +1,85 @@ +cang = new CANG(range('A', 'Z'), 8); + } + + public function run(int $startId, int $endId, bool $warmup = true): void + { + echo "=== CANG BENCHMARK ===\n"; + echo "Range: $startId → $endId\n"; + echo "Total IDs: " . ($endId - $startId + 1) . "\n\n"; + + if ($warmup) { + $this->warmup(); + } + + $this->benchmark($startId, $endId); + } + + // --------------------------------------------------------- + // WARMUP (optional) + // --------------------------------------------------------- + + protected function warmup(): void + { + echo "--- Warmup Pass (stabilizing CPU cache) ---\n"; + + $this->cang->generate(CANG::MODE_ID, "0"); + $this->cang->generate(CANG::MODE_ID, "1000"); + $this->cang->generate(CANG::MODE_ID, "500000"); + + echo "Warmup complete.\n\n"; + } + + // --------------------------------------------------------- + // MAIN BENCHMARK + // --------------------------------------------------------- + + protected function benchmark(int $startId, int $endId): void + { + echo "--- Running Benchmark ---\n"; + + $count = $endId - $startId + 1; + + $startTime = microtime(true); + $startMemory = memory_get_usage(true); + + for ($i = $startId; $i <= $endId; $i++) { + $this->cang->generate(CANG::MODE_ID, (string)$i); + } + + $endTime = microtime(true); + $endMemory = memory_get_usage(true); + + $duration = $endTime - $startTime; + $memoryUsed = $endMemory - $startMemory; + $avgPerId = $duration / $count; + $idsPerSecond = $count / $duration; + + echo "Duration: " . number_format($duration, 6) . " sec\n"; + echo "Avg per ID: " . number_format($avgPerId, 9) . " sec\n"; + echo "IDs per second: " . number_format($idsPerSecond, 2) . "\n"; + echo "Memory used: " . number_format($memoryUsed / 1024, 2) . " KB\n"; + + echo "\n--- Benchmark Complete ---\n"; + } +} + +/* +Example: How To Benchmark + +require "CANG.php"; +require "CANG_Benchmark.php"; + +$bench = New CANG_Benchmark(); + +// Example: benchmark 0 → 1,000,000 +$bench->run(0, 1000000); +*/ +?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_MS_G.php b/v.0.5.FinallVersion/Base_CANG_Generators/CANG_MS_G.php new file mode 100644 index 0000000..e69de29 diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php b/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php new file mode 100644 index 0000000..ad75c44 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php @@ -0,0 +1,119 @@ +cang = new CANG(range('A', 'Z'), 8); + } + + public function run(): void + { + echo "=== CANG TEST SUITE ===\n\n"; + + $this->testBeginning(); + $this->testEnd(); + $this->testRandom(); + $this->testIdMode(); + $this->testNextPrevious(); + $this->testStringPositionMapping(); + + echo "\n=== TESTING COMPLETE ===\n"; + } + + protected function assertEqual($expected, $actual, string $label): void + { + $status = ($expected === $actual) ? "PASS" : "FAIL"; + echo sprintf( + "%-30s : %-5s | Expected: %-12s Got: %-12s\n", + $label, + $status, + $expected, + $actual + ); + } + + // --------------------------------------------------------- + // INDIVIDUAL TESTS + // --------------------------------------------------------- + + protected function testBeginning(): void + { + echo "--- Beginning Mode ---\n"; + $result = $this->cang->generate(CANG::MODE_BEGINNING); + $this->assertEqual("AAAAAAAA", $result, "Beginning"); + echo "\n"; + } + + protected function testEnd(): void + { + echo "--- End Mode ---\n"; + $result = $this->cang->generate(CANG::MODE_END); + $this->assertEqual("ZZZZZZZZ", $result, "End"); + echo "\n"; + } + + protected function testRandom(): void + { + echo "--- Random Mode ---\n"; + $result = $this->cang->generate(CANG::MODE_RANDOM); + echo "Random Output: $result\n\n"; + } + + protected function testIdMode(): void + { + echo "--- ID Mode ---\n"; + $this->assertEqual("AAAAAAAA", $this->cang->generate(CANG::MODE_ID, "0"), "ID 0"); + $this->assertEqual("AAAAAAAB", $this->cang->generate(CANG::MODE_ID, "1"), "ID 1"); + $this->assertEqual("AAAAAAAC", $this->cang->generate(CANG::MODE_ID, "2"), "ID 2"); + echo "\n"; + } + + protected function testNextPrevious(): void + { + echo "--- Next / Previous ---\n"; + + $this->assertEqual( + "AAAAAAAC", + $this->cang->generate(CANG::MODE_NEXT, "AAAAAAAB"), + "Next" + ); + + $this->assertEqual( + "AAAAAAAB", + $this->cang->generate(CANG::MODE_PREVIOUS, "AAAAAAAC"), + "Previous" + ); + + echo "\n"; + } + + protected function testStringPositionMapping(): void + { + echo "--- String <-> Position ---\n"; + + $this->assertEqual(0, $this->cang->stringToPosition("AAAAAAAA"), "Pos AAAAAAAA"); + $this->assertEqual(1, $this->cang->stringToPosition("AAAAAAAB"), "Pos AAAAAAAB"); + $this->assertEqual(2, $this->cang->stringToPosition("AAAAAAAC"), "Pos AAAAAAAC"); + + $this->assertEqual("AAAAAAAA", $this->cang->positionToString(0), "Str 0"); + $this->assertEqual("AAAAAAAB", $this->cang->positionToString(1), "Str 1"); + $this->assertEqual("AAAAAAAC", $this->cang->positionToString(2), "Str 2"); + + echo "\n"; + } +} + +/* +Example: How To Test + +require "CANG.php"; +require "CANG_Test.php"; + +$CANGTest = New CANG_Test(); +$CANGTest->run(); + +*/ +?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php new file mode 100644 index 0000000..23a024c --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php new file mode 100644 index 0000000..29e842e --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php @@ -0,0 +1,151 @@ +id = $id; + $this->name = $name; + $this->type = $type; + $this->description = $description; + $this->range = $range; + } + + // ----------------------------- + // Accessors + // ----------------------------- + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getType(): string + { + return $this->type; + } + + public function getDescription(): string + { + return $this->description; + } + + public function getRange(): array + { + return $this->range; + } + + // ----------------------------- + // Utility + // ----------------------------- + + public function getFlattenedRange(): array + { + return array_merge(...$this->range); + } + + public function containsChar(string $char): bool + { + return in_array($char, $this->getFlattenedRange(), true); + } + + // ----------------------------- + // Factory: Build All Definitions + // ----------------------------- + + public static function BuildAll(array $LanguageChar): array + { + $LanguageName = [ + 1 => 'Alphabet_Upper', + 2 => 'Alphabet_Lower', + 3 => 'Alphabet_Mix', + 4 => 'Numeric', + 5 => 'Alphabet_Upper_Num', + 6 => 'Alphabet_Lower_Num', + 7 => 'Alphabet_Mix_Num', + 8 => 'Alphabet_Mix_Num_SpecialShort', + 9 => 'Alphabet_Mix_Num_SpecialFull' + ]; + + $LanguageType = [ + 1 => '[A-Z]', + 2 => '[a-z]', + 3 => '[A-Z,a-z]', + 4 => '[0-9]', + 5 => '[A-Z,0-9]', + 6 => '[a-z,0-9]', + 7 => '[A-Z,a-z,0-9]', + 8 => '[A-Z,a-z,0-9,-_]', + 9 => '[A-Z,a-z,0-9,-_]' + ]; + + $LanguageDescription = [ + 1 => 'Alphabetical -> Simple: Capital letters', + 2 => 'Alphabetical -> Simple: Small letters', + 3 => 'Alphabetical -> Mix: Capital and Small letters', + 4 => 'Numerical -> Simple', + 5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', + 6 => 'Alphabetical and Numerical -> Simple: Small letters', + 7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', + 8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', + 9 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' + ]; + + $LanguageRange = [ + 1 => [$LanguageChar['Upper']], + 2 => [$LanguageChar['Lower']], + 3 => [$LanguageChar['Upper'], $LanguageChar['Lower']], + 4 => [$LanguageChar['Numeric']], + 5 => [$LanguageChar['Upper'], $LanguageChar['Numeric']], + 6 => [$LanguageChar['Lower'], $LanguageChar['Numeric']], + 7 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric']], + 8 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['ShortSpecial']], + 9 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['FullSpecial']] + ]; + + $definitions = []; + + foreach (range(1, 9) As $id) { + $definitions[$id] = New Self( + $id, + $LanguageName[$id], + $LanguageType[$id], + $LanguageDescription[$id], + $LanguageRange[$id] + ); + } + + return $definitions; + } +} + +/* +Example: How To Use + +Insert This To Include LanguageChar Configuration: +$CANG_LanguageCharFoundation = require __DIR__ . '/CANG_Config/CANG_LanguageCharFoundation.php'; + +Then Load The LanguageDefinition: +$CANG_LanguageDefinition = LanguageDefinition::BuildAll($CANG_LanguageCharFoundation['LanguageChar']); + +You Can Print The OutPut And Continue To Configure Your FrameWork: +print_r($CANG_LanguageDefinition); + +*/ +?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php new file mode 100644 index 0000000..54d5146 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php @@ -0,0 +1,88 @@ + range('A', 'Z'), + 'Lower' => range('a', 'z'), + 'Numeric' => range('0', '9'), + 'ShortSpecial' => str_split('_-'), + 'FullSpecial' => str_split('#$%&+-@_') +]; + +/** + * Basic Language Names + */ +$LanguageName = [ + 1 => 'Alphabet_Upper', + 2 => 'Alphabet_Lower', + 3 => 'Alphabet_Mix', + 4 => 'Numeric', + 5 => 'Alphabet_Upper_Num', + 6 => 'Alphabet_Lower_Num', + 7 => 'Alphabet_Mix_Num', + 8 => 'Alphabet_Mix_Num_SpecialShort', + 9 => 'Alphabet_Mix_Num_SpecialFull' +]; + +/** + * Basic Language Types + */ +$LanguageType = [ + 1 => '[A-Z]', + 2 => '[a-z]', + 3 => '[A-Z,a-z]', + 4 => '[0-9]', + 5 => '[A-Z,0-9]', + 6 => '[a-z,0-9]', + 7 => '[A-Z,a-z,0-9]', + 8 => '[A-Z,a-z,0-9,-_]', + 9 => '[A-Z,a-z,0-9,-_]' +]; + +/** + * Basic Language Descriptions + */ +$LanguageDescription = [ + 1 => 'Alphabetical -> Simple: Capital letters', + 2 => 'Alphabetical -> Simple: Small letters', + 3 => 'Alphabetical -> Mix: Capital and Small letters', + 4 => 'Numerical -> Simple', + 5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', + 6 => 'Alphabetical and Numerical -> Simple: Small letters', + 7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', + 8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', + 9 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' +]; + +/** + * Basic Language Ranges + */ +$LanguageRange = [ + 1 => [$LanguageChar['Upper']], + 2 => [$LanguageChar['Lower']], + 3 => [$LanguageChar['Upper'], $LanguageChar['Lower']], + 4 => [$LanguageChar['Numeric']], + 5 => [$LanguageChar['Upper'], $LanguageChar['Numeric']], + 6 => [$LanguageChar['Lower'], $LanguageChar['Numeric']], + 7 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric']], + 8 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['ShortSpecial']], + 9 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['FullSpecial']] +]; + +/** + * Language Definition (Ordered) + */ +$LanguageDefinition = []; + +foreach (range(1, 9) as $id) { + $LanguageDefinition[$id] = [ + 'LanguageId' => $id, + 'LanguageName' => $LanguageName[$id], + 'LanguageType' => $LanguageType[$id], + 'LanguageDescription' => $LanguageDescription[$id], + 'LanguageRange' => $LanguageRange[$id], + ]; +} +?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID.php new file mode 100644 index 0000000..bc08463 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID.php @@ -0,0 +1,8 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php new file mode 100644 index 0000000..7f7170c --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php @@ -0,0 +1,9 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID +header("Content-type:application/json"); +echo json_encode($return,true); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random.php new file mode 100644 index 0000000..d9185db --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random.php @@ -0,0 +1,8 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_String(); +print_r($return); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php new file mode 100644 index 0000000..ba850c8 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php @@ -0,0 +1,9 @@ +SetLength(8); +$CANG->SetType(5); +$return = $CANG->Generate_String(); +header("Content-type:application/json"); +echo json_encode($return,true); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String.php new file mode 100644 index 0000000..a843dd4 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String.php @@ -0,0 +1,11 @@ +SetLength(8); +$CANG->SetType(5); +$CANG->CodeInput(); +$return[1] = $CANG->Generate_String(); +$CANG->CodeInput($return[1]['code_base']); +$return[] = $CANG->Generate_String(); +print_r($return); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String_JSON.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String_JSON.php new file mode 100644 index 0000000..8050c54 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String_JSON.php @@ -0,0 +1,12 @@ +SetLength(8); +$CANG->SetType(5); +$CANG->CodeInput(); +$return[1] = $CANG->Generate_String(); +$CANG->CodeInput($return[1]['code_base']); +$return[] = $CANG->Generate_String(); +header("Content-type:application/json"); +echo json_encode($return,true); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php new file mode 100644 index 0000000..02f3262 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php @@ -0,0 +1,6 @@ +byID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php new file mode 100644 index 0000000..55a9877 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php @@ -0,0 +1,7 @@ +byID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID +header("Content-type:application/json"); +echo json_encode($return,true); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php new file mode 100644 index 0000000..e38b1f0 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php @@ -0,0 +1,6 @@ +byRAND();//In 30 seconds you should be able to generate the key by this ID +print_r($return); +?> diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php new file mode 100644 index 0000000..d41c3a5 --- /dev/null +++ b/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php @@ -0,0 +1,7 @@ +byRAND();//In 30 seconds you should be able to generate the key by this ID +header("Content-type:application/json"); +echo json_encode($return,true) +?> From a4756c88db9b3c72442c0e07d07ca7575a07c954 Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sat, 10 Jan 2026 17:31:55 +0100 Subject: [PATCH 64/72] Add header for CANG details in README --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..636cd76 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Write Down Details Of The CANG From 31c038759475976a00cb8688d9794191afba684f Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sun, 11 Jan 2026 00:14:49 +0100 Subject: [PATCH 65/72] Update README And Some Structure - Almost Working Order. --- README.md | 206 ++++++++++++++++++ v.0.5.FinallVersion/Base_CANG_CommandAI.md | 35 +++ v.0.5.FinallVersion/Base_CANG_Display.php | 74 +++++++ .../Base_CANG_Language/CANG_LanguageClass.php | 2 +- 4 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..8d44521 --- /dev/null +++ b/README.md @@ -0,0 +1,206 @@ +Below is a polished, reference‑quality **README.md** you can drop directly into a GitHub repository. +It’s structured, logical, developer‑friendly, and explains the full CANG language‑selection system with clarity and purpose. + +--- + +# **CANG — Configurable Alphanumeric Generator** + +CANG is a lightweight, extensible system for generating strings based on predefined *language profiles*. +Each profile defines a **character set**, a **logical type**, and a **semantic description**, allowing developers to produce output strings that match specific formatting, security, or compatibility requirements. + +CANG is ideal for: + +- Token generation +- File‑ID or resource‑ID creation +- URL‑safe identifiers +- Password or key generation +- Systems requiring predictable, rule‑driven output formats + +--- + +## 🔧 **Core Concept** + +CANG operates on a simple principle: + +> **Choose a Language → Load Its Character Set → Generate a Compatible Output String** + +Each *Language* is defined by: + +- **Language Name** — Human‑readable identifier +- **Language Type** — Regex‑style character class +- **Language Description** — Semantic explanation of intended use + +--- + +# 📚 **Language Reference Table** + +| ID | Language Name | Language Type | Description | +|----|---------------|---------------|-------------| +| 1 | `Alphabet_Upper` | `[A-Z]` | Alphabetical → Simple: Capital letters | +| 2 | `Alphabet_Lower` | `[a-z]` | Alphabetical → Simple: Small letters | +| 3 | `Alphabet_Mix` | `[A-Z,a-z]` | Alphabetical → Mix: Capital and Small letters | +| 4 | `Numeric` | `[0-9]` | Numerical → Simple | +| 5 | `Alphabet_Upper_Num` | `[A-Z,0-9]` | Alphabetical + Numerical → Simple: Capital letters (Megaupload‑style) | +| 6 | `Alphabet_Lower_Num` | `[a-z,0-9]` | Alphabetical + Numerical → Simple: Small letters | +| 7 | `Alphabet_Mix_Num` | `[A-Z,a-z,0-9]` | Alphabetical + Numerical → Mix: Capital and Small letters | +| 8 | `Alphabet_Mix_Num_SpecialShort` | `[A-Z,a-z,0-9,-_]` | Mix + Short Special chars (YouTube‑style) | +| 9 | `Alphabet_Mix_Num_SpecialFull` | `[A-Z,a-z,0-9,-_]` | Mix + Full Special chars (Safe Password) | + +--- + +# 🧠 **Language Selector Logic** + +CANG uses a simple numeric selector to load the correct language profile. + +### **Example Selector Map** + +```php +$CANG_Language = [ + 1 => 'Alphabet_Upper', + 2 => 'Alphabet_Lower', + 3 => 'Alphabet_Mix', + 4 => 'Numeric', + 5 => 'Alphabet_Upper_Num', + 6 => 'Alphabet_Lower_Num', + 7 => 'Alphabet_Mix_Num', + 8 => 'Alphabet_Mix_Num_SpecialShort', + 9 => 'Alphabet_Mix_Num_SpecialFull' +]; +``` + +### **Character Set Definitions** + +```php +$CANG_Type = [ + 1 => '[A-Z]', + 2 => '[a-z]', + 3 => '[A-Z,a-z]', + 4 => '[0-9]', + 5 => '[A-Z,0-9]', + 6 => '[a-z,0-9]', + 7 => '[A-Z,a-z,0-9]', + 8 => '[A-Z,a-z,0-9,-_]', + 9 => '[A-Z,a-z,0-9,-_]' +]; +``` + +### **Descriptions** + +```php +$CANG_Description = [ + 1 => 'Alphabetical -> Simple: Capital letters', + 2 => 'Alphabetical -> Simple: Small letters', + 3 => 'Alphabetical -> Mix: Capital and Small letters', + 4 => 'Numerical -> Simple', + 5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', + 6 => 'Alphabetical and Numerical -> Simple: Small letters', + 7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', + 8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', + 9 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' +]; +``` + +--- + +# ⚙️ **How CANG Works Internally** + +### **1. Select a Language ID** + +```php +$languageID = 7; // Alphabet_Mix_Num +``` + +### **2. Load the Character Set** + +```php +$charset = $CANG_Type[$languageID]; +``` + +### **3. Convert Character Class to Actual Characters** + +Example logic: + +```php +function expandCharset($pattern) { + $chars = ''; + + if (strpos($pattern, 'A-Z') !== false) { + $chars .= implode('', range('A', 'Z')); + } + if (strpos($pattern, 'a-z') !== false) { + $chars .= implode('', range('a', 'z')); + } + if (strpos($pattern, '0-9') !== false) { + $chars .= implode('', range('0', '9')); + } + if (strpos($pattern, '-') !== false) { + $chars .= '-'; + } + if (strpos($pattern, '_') !== false) { + $chars .= '_'; + } + + return $chars; +} +``` + +### **4. Generate Output String** + +```php +function CANG_Generate($charset, $length = 12) { + $output = ''; + $max = strlen($charset) - 1; + + for ($i = 0; $i < $length; $i++) { + $output .= $charset[random_int(0, $max)]; + } + + return $output; +} +``` + +### **5. Full Example** + +```php +$charset = expandCharset($CANG_Type[$languageID]); +$token = CANG_Generate($charset, 16); + +echo $token; // Example: Ab9ZtQ3mP1xR7cD2 +``` + +--- + +# 🚀 **Use Cases** + +| Use Case | Recommended Language | +|---------|----------------------| +| Simple uppercase IDs | `Alphabet_Upper` | +| Lowercase slugs | `Alphabet_Lower` | +| Human‑friendly mixed IDs | `Alphabet_Mix` | +| Numeric codes | `Numeric` | +| Legacy file hosts (Microsoft/Megaupload‑style) | `Alphabet_Upper_Num` | +| Lowercase URL tokens | `Alphabet_Lower_Num` | +| General‑purpose tokens | `Alphabet_Mix_Num` | +| YouTube‑style video IDs | `Alphabet_Mix_Num_SpecialShort` | +| Secure passwords | `Alphabet_Mix_Num_SpecialFull` | + +--- + +# 🧩 **Extending CANG** + +CANG is intentionally modular. +To add a new language: + +1. Add a new entry to **Language Name** +2. Add a matching **Language Type** +3. Add a **Description** +4. Ensure your charset parser supports the new pattern + +This design keeps CANG future‑proof and easy to evolve. + +--- + +# 🏁 **Conclusion** + +CANG provides a clean, structured, and extensible way to generate strings with predictable rules. +Its language‑based architecture makes it ideal for developers who value clarity, control, and compatibility across systems. \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_CommandAI.md b/v.0.5.FinallVersion/Base_CANG_CommandAI.md index 8bdd3fc..5cc23f4 100644 --- a/v.0.5.FinallVersion/Base_CANG_CommandAI.md +++ b/v.0.5.FinallVersion/Base_CANG_CommandAI.md @@ -103,3 +103,38 @@ Example: AAAAAAAA = 0 AAAAAAAB = 1 AAAAAAAC = 2 + +ReadMe: +Write Nice Referencial ReadMe MarkDown With Logic And Development For GitHub About The CANG That Includes Language Char Followed By Language Definition And Language Selector To Gain Settings For CANG And Generate OutPut String That Is Compatible According To +Language Name: +1 => 'Alphabet_Upper', +2 => 'Alphabet_Lower', +3 => 'Alphabet_Mix', +4 => 'Numeric', +5 => 'Alphabet_Upper_Num', +6 => 'Alphabet_Lower_Num', +7 => 'Alphabet_Mix_Num', +8 => 'Alphabet_Mix_Num_SpecialShort', +9 => 'Alphabet_Mix_Num_SpecialFull' + +Language Type: +1 => '[A-Z]', +2 => '[a-z]', +3 => '[A-Z,a-z]', +4 => '[0-9]', +5 => '[A-Z,0-9]', +6 => '[a-z,0-9]', +7 => '[A-Z,a-z,0-9]', +8 => '[A-Z,a-z,0-9,-_]', +9 => '[A-Z,a-z,0-9,-_]' + +Language Description: +1 => 'Alphabetical -> Simple: Capital letters', +2 => 'Alphabetical -> Simple: Small letters', +3 => 'Alphabetical -> Mix: Capital and Small letters', +4 => 'Numerical -> Simple', +5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', +6 => 'Alphabetical and Numerical -> Simple: Small letters', +7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', +8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', +9 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' diff --git a/v.0.5.FinallVersion/Base_CANG_Display.php b/v.0.5.FinallVersion/Base_CANG_Display.php index e69de29..2543664 100644 --- a/v.0.5.FinallVersion/Base_CANG_Display.php +++ b/v.0.5.FinallVersion/Base_CANG_Display.php @@ -0,0 +1,74 @@ +Definition = $LanguageAll; + + } + + public function Input(array $Input){ + $this->Definition = $Input; + } + + public function SelectId(int $Id){ + + foreach(range(0,Count($this->Definition)) As $LanguageId){ + + if($LanguageId == $Id){ + $this->Id = $Id; + $this->OutPut = $this->Definition[$Id]; + } + } + } + + public function SelectName(string $Name){ + // Find name in definition and define output + foreach($this->Definition As $LanguageTable){ + + if($LanguageTable['Name'] == $Name){ + $this->Name = $Name; + $this->OutPut = $LanguageTable; + } + } + } + + public function GetOutPut(){ + return $this->OutPut; + } + +} + +/* +// Insert This To Run CANG: +$CANG = New CANG($CANG_LanguageDefinition, 8); + +echo $CANG->generate(CANG::MODE_BEGINNING); // AAAAAAAA +echo $CANG->generate(CANG::MODE_ID, "0"); // AAAAAAAA +echo $CANG->generate(CANG::MODE_ID, "1"); // AAAAAAAB +echo $CANG->generate(CANG::MODE_ID, "2"); // AAAAAAAC +echo $CANG->generate(CANG::MODE_NEXT, "AAAAAAAB"); // AAAAAAAC +echo $CANG->stringToPosition("AAAAAAAC"); // 2 +*/ +?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php index 29e842e..b4e1c31 100644 --- a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php +++ b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php @@ -142,7 +142,7 @@ public static function BuildAll(array $LanguageChar): array $CANG_LanguageCharFoundation = require __DIR__ . '/CANG_Config/CANG_LanguageCharFoundation.php'; Then Load The LanguageDefinition: -$CANG_LanguageDefinition = LanguageDefinition::BuildAll($CANG_LanguageCharFoundation['LanguageChar']); +$CANG_LanguageDefinition = CANG_LanguageDefinition::BuildAll($CANG_LanguageCharFoundation['LanguageChar']); You Can Print The OutPut And Continue To Configure Your FrameWork: print_r($CANG_LanguageDefinition); From 28ceb90063df8edd22a58b70784c114fec1b41ab Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sun, 11 Jan 2026 02:18:58 +0100 Subject: [PATCH 66/72] Update By Class CANG_LanguageSelect And Append All Files To Continue To Next Step --- README.md | 4 - ...arFoundation.php => CANG_LanguageChar.php} | 4 +- v.0.5.FinallVersion/Base_CANG_Display.php | 99 ++++++++++--------- ...uageClass.php => CANG_LanguageProfile.php} | 11 ++- 4 files changed, 61 insertions(+), 57 deletions(-) rename v.0.5.FinallVersion/Base_CANG_Config/{CANG_LanguageCharFoundation.php => CANG_LanguageChar.php} (92%) rename v.0.5.FinallVersion/Base_CANG_Language/{CANG_LanguageClass.php => CANG_LanguageProfile.php} (91%) diff --git a/README.md b/README.md index 2146fc8..78c979e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -<<<<<<< HEAD Below is a polished, reference‑quality **README.md** you can drop directly into a GitHub repository. It’s structured, logical, developer‑friendly, and explains the full CANG language‑selection system with clarity and purpose. @@ -205,6 +204,3 @@ This design keeps CANG future‑proof and easy to evolve. CANG provides a clean, structured, and extensible way to generate strings with predictable rules. Its language‑based architecture makes it ideal for developers who value clarity, control, and compatibility across systems. -======= -# Write Down Details Of The CANG ->>>>>>> a4756c88db9b3c72442c0e07d07ca7575a07c954 diff --git a/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageCharFoundation.php b/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php similarity index 92% rename from v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageCharFoundation.php rename to v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php index ae57b25..2e0b5f9 100644 --- a/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageCharFoundation.php +++ b/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php @@ -33,10 +33,10 @@ /* Example: How To Use -$LanguageCharFoundation = require __DIR__ . '/CANG_Config/CANG_LanguageCharFoundation.php'; +$LanguageCharFoundation = require __DIR__ . '/CANG_Config/CANG_LanguageChar.php'; Then Insert This Code Into Process: -$LanguageCharFoundation['LanguageChar'] +$LanguageChar['LanguageChar'] It Will Help You To Match The Configuration InSide The Array. */ diff --git a/v.0.5.FinallVersion/Base_CANG_Display.php b/v.0.5.FinallVersion/Base_CANG_Display.php index 2543664..a9bc538 100644 --- a/v.0.5.FinallVersion/Base_CANG_Display.php +++ b/v.0.5.FinallVersion/Base_CANG_Display.php @@ -1,65 +1,72 @@ Definition = $LanguageAll; +class CANG_LanguageSelect +{ + protected array $definitions; + public function __construct(array $definitions) + { + $this->definitions = $definitions; } - public function Input(array $Input){ - $this->Definition = $Input; - } + // --------------------------------------------------------- + // Selectors + // --------------------------------------------------------- - public function SelectId(int $Id){ - - foreach(range(0,Count($this->Definition)) As $LanguageId){ - - if($LanguageId == $Id){ - $this->Id = $Id; - $this->OutPut = $this->Definition[$Id]; - } - } + public function byId(int $id): ?CANG_LanguageProfile + { + return $this->definitions[$id] ?? null; } - public function SelectName(string $Name){ - // Find name in definition and define output - foreach($this->Definition As $LanguageTable){ - - if($LanguageTable['Name'] == $Name){ - $this->Name = $Name; - $this->OutPut = $LanguageTable; + public function byName(string $name): ?CANG_LanguageProfile + { + foreach ($this->definitions as $definition) { + if ($definition->getName() === $name) { + return $definition; } } + return null; } - public function GetOutPut(){ - return $this->OutPut; + // --------------------------------------------------------- + // Output Formatter + // --------------------------------------------------------- + + public function output(CANG_LanguageProfile $definition): array + { + return [ + 'id' => $definition->getId(), + 'name' => $definition->getName(), + 'type' => $definition->getType(), + 'description' => $definition->getDescription(), + 'range' => $definition->getRange(), + 'flattened' => $definition->getFlattenedRange(), + ]; } - } +// Insert This To Include LanguageChar Configuration: +$CANG_LanguageChar = require __DIR__ . '/Base_CANG_Config/CANG_LanguageChar.php'; + +// Insert This To Include Language Class: +require __DIR__ . '/Base_CANG_Language/CANG_LanguageProfile.php'; + +// Inssert This To Include CANG Class: +// require __DIR__ . '/Base_CANG_Generators/CANG.php'; + +// Then Load The LanguageDefinition: +$CANG_LanguageProfile = CANG_LanguageProfile::BuildAll($CANG_LanguageChar['LanguageChar']); + +// You Can Print The OutPut And Continue To Configure Your FrameWork: +//print_r($CANG_LanguageProfile); + +$CANG_LanguageSelect = New CANG_LanguageSelect($CANG_LanguageProfile); +$CANG_LanguageRange = $CANG_LanguageSelect->byName('Alphabet_Upper'); +$CANG_LanguageOutPut = $CANG_LanguageSelect->output($CANG_LanguageRange); +print_r($CANG_LanguageOutPut); + /* // Insert This To Run CANG: $CANG = New CANG($CANG_LanguageDefinition, 8); diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php similarity index 91% rename from v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php rename to v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php index b4e1c31..cd6b47a 100644 --- a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageClass.php +++ b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php @@ -1,6 +1,6 @@ \ No newline at end of file From 27dc7927d6e380ead0075d52fef6188a4f63414e Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sun, 11 Jan 2026 02:32:45 +0100 Subject: [PATCH 67/72] Update: Removed Examples Which Will Be Moved To Different Area. --- .../Base_CANG_Config/CANG_LanguageChar.php | 11 ---- v.0.5.FinallVersion/Base_CANG_Display.php | 56 ++----------------- .../CANG_LanguageProfile.php | 14 ----- .../CANG_LanguageSelect.php | 49 ++++++++++++++++ 4 files changed, 55 insertions(+), 75 deletions(-) create mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php diff --git a/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php b/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php index 2e0b5f9..8432bce 100644 --- a/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php +++ b/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php @@ -29,15 +29,4 @@ ], ]; - -/* -Example: How To Use - -$LanguageCharFoundation = require __DIR__ . '/CANG_Config/CANG_LanguageChar.php'; - -Then Insert This Code Into Process: -$LanguageChar['LanguageChar'] -It Will Help You To Match The Configuration InSide The Array. -*/ - ?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Display.php b/v.0.5.FinallVersion/Base_CANG_Display.php index a9bc538..f4f63e3 100644 --- a/v.0.5.FinallVersion/Base_CANG_Display.php +++ b/v.0.5.FinallVersion/Base_CANG_Display.php @@ -1,73 +1,29 @@ definitions = $definitions; - } - - // --------------------------------------------------------- - // Selectors - // --------------------------------------------------------- - - public function byId(int $id): ?CANG_LanguageProfile - { - return $this->definitions[$id] ?? null; - } - - public function byName(string $name): ?CANG_LanguageProfile - { - foreach ($this->definitions as $definition) { - if ($definition->getName() === $name) { - return $definition; - } - } - return null; - } - - // --------------------------------------------------------- - // Output Formatter - // --------------------------------------------------------- - - public function output(CANG_LanguageProfile $definition): array - { - return [ - 'id' => $definition->getId(), - 'name' => $definition->getName(), - 'type' => $definition->getType(), - 'description' => $definition->getDescription(), - 'range' => $definition->getRange(), - 'flattened' => $definition->getFlattenedRange(), - ]; - } -} - // Insert This To Include LanguageChar Configuration: $CANG_LanguageChar = require __DIR__ . '/Base_CANG_Config/CANG_LanguageChar.php'; // Insert This To Include Language Class: require __DIR__ . '/Base_CANG_Language/CANG_LanguageProfile.php'; -// Inssert This To Include CANG Class: -// require __DIR__ . '/Base_CANG_Generators/CANG.php'; - // Then Load The LanguageDefinition: $CANG_LanguageProfile = CANG_LanguageProfile::BuildAll($CANG_LanguageChar['LanguageChar']); // You Can Print The OutPut And Continue To Configure Your FrameWork: //print_r($CANG_LanguageProfile); +require __DIR__ . '/Base_CANG_Language/CANG_LanguageSelect.php'; + $CANG_LanguageSelect = New CANG_LanguageSelect($CANG_LanguageProfile); $CANG_LanguageRange = $CANG_LanguageSelect->byName('Alphabet_Upper'); $CANG_LanguageOutPut = $CANG_LanguageSelect->output($CANG_LanguageRange); print_r($CANG_LanguageOutPut); /* + +// Inssert This To Include CANG Class: +// require __DIR__ . '/Base_CANG_Generators/CANG.php'; + // Insert This To Run CANG: $CANG = New CANG($CANG_LanguageDefinition, 8); diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php index cd6b47a..d27531d 100644 --- a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php +++ b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php @@ -135,18 +135,4 @@ public static function BuildAll(array $LanguageChar): array return $definitions; } } - -/* -Example: How To Use - -Insert This To Include LanguageChar Configuration: -$CANG_LanguageChar = require __DIR__ . '/CANG_Config/CANG_LanguageChar.php'; - -Then Load The LanguageDefinition: -$CANG_LanguageProfile = CANG_LanguageProfile::BuildAll($CANG_LanguageChar['LanguageChar']); - -You Can Print The OutPut And Continue To Configure Your FrameWork: -print_r($CANG_LanguageProfile); - -*/ ?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php new file mode 100644 index 0000000..193a000 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php @@ -0,0 +1,49 @@ +definitions = $definitions; + } + + // --------------------------------------------------------- + // Selectors + // --------------------------------------------------------- + + public function byId(int $id): ?CANG_LanguageProfile + { + return $this->definitions[$id] ?? null; + } + + public function byName(string $name): ?CANG_LanguageProfile + { + foreach ($this->definitions as $definition) { + if ($definition->getName() === $name) { + return $definition; + } + } + return null; + } + + // --------------------------------------------------------- + // Output Formatter + // --------------------------------------------------------- + + public function output(CANG_LanguageProfile $definition): array + { + return [ + 'id' => $definition->getId(), + 'name' => $definition->getName(), + 'type' => $definition->getType(), + 'description' => $definition->getDescription(), + 'range' => $definition->getRange(), + 'flattened' => $definition->getFlattenedRange(), + ]; + } +} +?> \ No newline at end of file From 4aa4015157f6e99188989d2ecca5d64de62a93cd Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sun, 11 Jan 2026 05:33:14 +0100 Subject: [PATCH 68/72] Update: README.md, Base_CANG_Display.php --- Complex_Alpha-Numeric_Generator.code-workspace | 6 +++++- README.md | 7 ++----- v.0.5.FinallVersion/Base_CANG_Display.php | 17 +++++++++++------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Complex_Alpha-Numeric_Generator.code-workspace b/Complex_Alpha-Numeric_Generator.code-workspace index 876a149..e1bb4fe 100644 --- a/Complex_Alpha-Numeric_Generator.code-workspace +++ b/Complex_Alpha-Numeric_Generator.code-workspace @@ -4,5 +4,9 @@ "path": "." } ], - "settings": {} + "settings": { + "editor.formatOnSave": true, + "files.autoSave": "afterDelay", + "editor.formatOnPaste": true + } } \ No newline at end of file diff --git a/README.md b/README.md index 78c979e..13370ea 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,3 @@ -Below is a polished, reference‑quality **README.md** you can drop directly into a GitHub repository. -It’s structured, logical, developer‑friendly, and explains the full CANG language‑selection system with clarity and purpose. - --- # **CANG — Configurable Alphanumeric Generator** @@ -40,7 +37,7 @@ Each *Language* is defined by: | 2 | `Alphabet_Lower` | `[a-z]` | Alphabetical → Simple: Small letters | | 3 | `Alphabet_Mix` | `[A-Z,a-z]` | Alphabetical → Mix: Capital and Small letters | | 4 | `Numeric` | `[0-9]` | Numerical → Simple | -| 5 | `Alphabet_Upper_Num` | `[A-Z,0-9]` | Alphabetical + Numerical → Simple: Capital letters (Megaupload‑style) | +| 5 | `Alphabet_Upper_Num` | `[A-Z,0-9]` | Alphabetical + Numerical → Simple: Capital letters (Microsoft/Megaupload‑style) | | 6 | `Alphabet_Lower_Num` | `[a-z,0-9]` | Alphabetical + Numerical → Simple: Small letters | | 7 | `Alphabet_Mix_Num` | `[A-Z,a-z,0-9]` | Alphabetical + Numerical → Mix: Capital and Small letters | | 8 | `Alphabet_Mix_Num_SpecialShort` | `[A-Z,a-z,0-9,-_]` | Mix + Short Special chars (YouTube‑style) | @@ -92,7 +89,7 @@ $CANG_Description = [ 2 => 'Alphabetical -> Simple: Small letters', 3 => 'Alphabetical -> Mix: Capital and Small letters', 4 => 'Numerical -> Simple', - 5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', + 5 => 'Alphabetical And Numerical -> Simple: Capital letters (Microsoft/Megaupload.com)', 6 => 'Alphabetical and Numerical -> Simple: Small letters', 7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', 8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', diff --git a/v.0.5.FinallVersion/Base_CANG_Display.php b/v.0.5.FinallVersion/Base_CANG_Display.php index f4f63e3..611fa3d 100644 --- a/v.0.5.FinallVersion/Base_CANG_Display.php +++ b/v.0.5.FinallVersion/Base_CANG_Display.php @@ -12,20 +12,25 @@ // You Can Print The OutPut And Continue To Configure Your FrameWork: //print_r($CANG_LanguageProfile); +// Insert This To Include CANG_LanguageSelect Class: require __DIR__ . '/Base_CANG_Language/CANG_LanguageSelect.php'; -$CANG_LanguageSelect = New CANG_LanguageSelect($CANG_LanguageProfile); -$CANG_LanguageRange = $CANG_LanguageSelect->byName('Alphabet_Upper'); -$CANG_LanguageOutPut = $CANG_LanguageSelect->output($CANG_LanguageRange); -print_r($CANG_LanguageOutPut); - /* +$CANG_LanguageSelect = new \CANG_LanguageSelect($CANG_LanguageProfile) +$CANG_LanguageRange = $CANG_LanguageSelect->byId(7); +print_r($Select->output($CANG_LanguageRange)); + +$CANG_LanguageSelect = new \CANG_LanguageSelect($CANG_LanguageProfile) +$CANG_LanguageRange = $CANG_LanguageSelect->byName('Alphabet_Mix_Num'); +print_r($Select->output($CANG_LanguageRange)); + + // Inssert This To Include CANG Class: // require __DIR__ . '/Base_CANG_Generators/CANG.php'; // Insert This To Run CANG: -$CANG = New CANG($CANG_LanguageDefinition, 8); +$CANG = New CANG($CANG_LanguageRange, 8); echo $CANG->generate(CANG::MODE_BEGINNING); // AAAAAAAA echo $CANG->generate(CANG::MODE_ID, "0"); // AAAAAAAA From 5d7f7cd368280fe36cbc9b384d684577bcb2be03 Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sun, 11 Jan 2026 05:49:51 +0100 Subject: [PATCH 69/72] Update: README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13370ea..687c441 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +Below is a polished, reference‑quality **README.md** you can drop directly into a GitHub repository. +It’s structured, logical, developer‑friendly, and explains the full CANG language‑selection system with clarity and purpose. + --- # **CANG — Configurable Alphanumeric Generator** @@ -200,4 +203,4 @@ This design keeps CANG future‑proof and easy to evolve. # 🏁 **Conclusion** CANG provides a clean, structured, and extensible way to generate strings with predictable rules. -Its language‑based architecture makes it ideal for developers who value clarity, control, and compatibility across systems. +Its language‑based architecture makes it ideal for developers who value clarity, control, and compatibility across systems. \ No newline at end of file From 37b99cd8fbaf0e890b77a29be63e057feae6172b Mon Sep 17 00:00:00 2001 From: Patrick ImProVision <2351449+PatrickImProVision@users.noreply.github.com> Date: Sun, 11 Jan 2026 09:23:47 +0100 Subject: [PATCH 70/72] Update: Base_CANG_Display.php, And Folder Renamed To Base_CANG_NoMySQL_Examples --- v.0.5.FinallVersion/Base_CANG_Display.php | 30 ++++++++++--------- .../Example_Generate_ID.php | 0 .../Example_Generate_ID_JSON.php | 0 .../Example_Generate_Random.php | 0 .../Example_Generate_Random_JSON.php | 0 .../Example_Generate_String.php | 0 .../Example_Generate_String_JSON.php | 0 .../Example_Microsoft_SN_Generate_ID.php | 0 .../Example_Microsoft_SN_Generate_ID_JSON.php | 0 .../Example_Microsoft_SN_Generate_Random.php | 0 ...mple_Microsoft_SN_Generate_Random_JSON.php | 0 11 files changed, 16 insertions(+), 14 deletions(-) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Generate_ID.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Generate_ID_JSON.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Generate_Random.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Generate_Random_JSON.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Generate_String.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Generate_String_JSON.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Microsoft_SN_Generate_ID.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Microsoft_SN_Generate_ID_JSON.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Microsoft_SN_Generate_Random.php (100%) rename v.0.5.FinallVersion/{Base_Examples_NoMySQL => Base_CANG_NoMySQL_Examples}/Example_Microsoft_SN_Generate_Random_JSON.php (100%) diff --git a/v.0.5.FinallVersion/Base_CANG_Display.php b/v.0.5.FinallVersion/Base_CANG_Display.php index 611fa3d..7d0d2c1 100644 --- a/v.0.5.FinallVersion/Base_CANG_Display.php +++ b/v.0.5.FinallVersion/Base_CANG_Display.php @@ -1,34 +1,37 @@ byId(7); -print_r($Select->output($CANG_LanguageRange)); - -$CANG_LanguageSelect = new \CANG_LanguageSelect($CANG_LanguageProfile) +// Or Select By Name $CANG_LanguageRange = $CANG_LanguageSelect->byName('Alphabet_Mix_Num'); +// OutPut Selection print_r($Select->output($CANG_LanguageRange)); - -// Inssert This To Include CANG Class: -// require __DIR__ . '/Base_CANG_Generators/CANG.php'; - // Insert This To Run CANG: $CANG = New CANG($CANG_LanguageRange, 8); @@ -39,4 +42,3 @@ echo $CANG->generate(CANG::MODE_NEXT, "AAAAAAAB"); // AAAAAAAC echo $CANG->stringToPosition("AAAAAAAC"); // 2 */ -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_ID_JSON.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_Random_JSON.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String_JSON.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Generate_String_JSON.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String_JSON.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_ID_JSON.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php diff --git a/v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php similarity index 100% rename from v.0.5.FinallVersion/Base_Examples_NoMySQL/Example_Microsoft_SN_Generate_Random_JSON.php rename to v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php From d65b6a36dc4601464d87bbd535a47e33cd4555e2 Mon Sep 17 00:00:00 2001 From: Patrick ImProVision Date: Tue, 17 Feb 2026 01:39:04 +0100 Subject: [PATCH 71/72] Update Development Complete Recostruction Of CANG, The Code Was Splited InTo Several Files To Make The Code AdjustAble WithOut Spagety Code Or One Function For All. All Errors Were Corrected. --- Example_Microsoft_SN.png | Bin 0 -> 44909 bytes .../Base_CANG/CANG_Data/CANG_Config.php | 45 ++ .../Base_CANG/CANG_Data/CANG_Language.php | 186 ++++++++ .../Base_CANG/CANG_Driver/CANG_Core.php | 338 ++++++++++++++ .../Base_CANG/CANG_Driver/CANG_DataBase.php | 187 ++++++++ .../Base_CANG/CANG_Driver/CANG_Driver.php | 367 +++++++++++++++ .../Base_CANG/CANG_Driver/CANG_ProFile.php | 325 +++++++++++++ .../CANG_MVC/CANG_Controller.php} | 0 .../Base_CANG/CANG_MVC/CANG_Module.php | 0 .../Base_CANG/CANG_MVC/CANG_Viewer.php | 0 .../Example_Generate_ID.php | 23 + .../Example_Generate_ID_JSON.php | 24 + .../Example_Generate_Random.php | 23 + .../Example_Generate_Random_JSON.php | 24 + .../Example_Generate_String.php | 26 ++ .../Example_Generate_String_JSON.php | 27 ++ .../Example_Microsoft_SN_Generate_ID.php | 26 ++ .../Example_Microsoft_SN_Generate_ID_JSON.php | 27 ++ .../Example_Microsoft_SN_Generate_Random.php | 26 ++ ...mple_Microsoft_SN_Generate_Random_JSON.php | 27 ++ .../Base_CANG_CommandAI.ExternalRules.md | 431 ++++++++++++++++++ v.0.5.FinallVersion/Base_CANG_CommandAI.md | 317 +++++++------ .../Base_CANG_Config/CANG_LanguageChar.php | 32 -- v.0.5.FinallVersion/Base_CANG_Display.php | 44 -- .../Base_CANG_Generators/CANG.php | 175 ------- .../Base_CANG_Generators/CANG_Benchmark.php | 85 ---- .../Base_CANG_Generators/CANG_Test.php | 119 ----- .../CANG_LanguageCharClass.php | 28 -- .../Base_CANG_Language/CANG_LanguageCode.php | 88 ---- .../CANG_LanguageProfile.php | 138 ------ .../CANG_LanguageSelect.php | 49 -- .../Example_Generate_ID.php | 8 - .../Example_Generate_ID_JSON.php | 9 - .../Example_Generate_Random.php | 8 - .../Example_Generate_Random_JSON.php | 9 - .../Example_Generate_String.php | 11 - .../Example_Generate_String_JSON.php | 12 - .../Example_Microsoft_SN_Generate_ID.php | 6 - .../Example_Microsoft_SN_Generate_ID_JSON.php | 7 - .../Example_Microsoft_SN_Generate_Random.php | 6 - ...mple_Microsoft_SN_Generate_Random_JSON.php | 7 - 41 files changed, 2317 insertions(+), 973 deletions(-) create mode 100644 Example_Microsoft_SN.png create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Config.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Language.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Core.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Driver.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_ProFile.php rename v.0.5.FinallVersion/{Base_CANG_Generators/CANG_MS_G.php => Base_CANG/CANG_MVC/CANG_Controller.php} (100%) create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Module.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Viewer.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String_JSON.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php create mode 100644 v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php create mode 100644 v.0.5.FinallVersion/Base_CANG_CommandAI.ExternalRules.md delete mode 100644 v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Display.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Generators/CANG.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String_JSON.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php delete mode 100644 v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php diff --git a/Example_Microsoft_SN.png b/Example_Microsoft_SN.png new file mode 100644 index 0000000000000000000000000000000000000000..557238e8bd042509faf01655d3d2fb49cfd80e42 GIT binary patch literal 44909 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

$6o=RUMe^`}yqPLI-(almW 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%0D3@bw7Gf0YS72pTZ-aQiO0XN6v3Z90szD| zpUIR)y%VGf!y>pKrgc4-4irui4uX*qcL_i zMU7daD$nT#g7%8dcN9Q)OZp_F3p(DDPSa9p?5j-OC(6RYWb)EDg8F09ufxCJ>>%v= z>$m&+d(8iX`M>l7h}FZxgTb4YF!~L>2LO1%u)yI-umon$0I+4y{S^T4o3lro8`=sv z*3CQYj34(0r6Wzhd+a|-MN`95vT=Xfoh`j&F`-4$6Uy7uYQF`0~s8OJs4 zc|w|T&-9+D4j4+q+)_=v9u?mKd zHm-}hVg827%-8E9D{jRYNVsQ*F@SuvTnv@m9}ojvQ#QEt@%c?pFxA6B4f8j?;NI>; zoR&jVRtS`a>-EqNP^k+P0RYm+zf^l7UBl3C@Pe&RE92c1KC!PnsO$SG85Lglod34YI`m3|hJ**2o#i<0` zo|Okvus2L~g2ZsJC1_^jgc0C=zrBKAg4AwVn2Wv6Cv|XVdNEzsM{zu|z^%8C6wkIx z5HhPH2z3jke9q>xsv3<@FAuyQR9NzT@R#hyB)00eS9M$ZiSoGAB25Lnt|lR76&tNI zQ^}h80as{~CRp#K-Yj#9NiHR^r8jexz8P|2i_{b@G)X0QOpXhjp?MWf+}E4gimn-4 zu}O}3?p)K(vo*aXh%nv2i|s;-m^rR$>MaiL)*Drm9CBHh$Z&?Poi{u!sz!|8UT<@V*vHn zr4V}nB-^%bj;KWB(c`c`*<2jm3>@-|p3kFW76l9AgW00r$DYT|${`8%`mP*m*k@D6 zqb!M2XG$|Wp1i~^;58YpC}}husVdBDDzC7gc%~yIXa{zQ;i^mD;w-RVAaVLh2&?@V ziErWYIMgSY=)}MtWlrk>Yym+Go<4xUw=IZqRcwvpZC;I#Ng{yo*G5fMWDE7NFdR<+ zFdYhE@aTE$1}=oqqtZ`2ihNtvjiy%dWVs ww_DE8$6mubpgnd4wu;m(J0TN2x{ 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 literal 0 HcmV?d00001 diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Config.php b/v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Config.php new file mode 100644 index 0000000..fbb2bb4 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Config.php @@ -0,0 +1,45 @@ +> + */ + public static function Build(): array + { + return [ + 'Language_Symbol' => [ + 'Upper' => range('A', 'Z'), + 'Lower' => range('a', 'z'), + 'Numeric' => range('0', '9'), + 'CharShort' => str_split('_-'), + 'CharLong' => str_split('#$%&+-@'), + ], + 'Language_Display' => [ + 'Upper' => '[A-Z]', + 'Lower' => '[a-z]', + 'Numeric' => '[0-9]', + 'CharShort' => '[-_]', + 'CharLong' => '[#$%&+-@]', + ], + ]; + } +} + +/* +Example usage: + +$LanguageConfig = CANG_Config::Build(); +$LanguageSymbol = $Config['Language_Symbol']; +$LanguageDisplay = $Config['Language_Display']; + + +// Quick run example when this file is executed directly. +if (realpath((string)($_SERVER['SCRIPT_FILENAME'] ?? '')) === __FILE__) { + $LanguageConfig = CANG_Config::Build(); + echo json_encode($LanguageConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL; +} +*/ \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Language.php b/v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Language.php new file mode 100644 index 0000000..b5a73f5 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_Data/CANG_Language.php @@ -0,0 +1,186 @@ +> + */ + public static function Build(): array + { + $config = CANG_Config::Build(); + + if (!isset($config['Language_Symbol'], $config['Language_Display'])) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + $Language_Symbol = $config['Language_Symbol']; + $Language_Display = $config['Language_Display']; + + return [ + 0 => [ + 'Language_Id' => 0, + 'Language_Name' => 'Alphabet_Upper', + 'Language_Type' => $Language_Display['Upper'], + 'Language_Description' => 'Alphabetical -> Simple: Capital Letters', + 'Language_Range' => [$Language_Symbol['Upper']], + ], + 1 => [ + 'Language_Id' => 1, + 'Language_Name' => 'Alphabet_Lower', + 'Language_Type' => $Language_Display['Lower'], + 'Language_Description' => 'Alphabetical -> Simple: Small Letters', + 'Language_Range' => [$Language_Symbol['Lower']], + ], + 2 => [ + 'Language_Id' => 2, + 'Language_Name' => 'Alphabet_Mix', + 'Language_Type' => [$Language_Display['Upper'], $Language_Display['Lower']], + 'Language_Description' => 'Alphabetical -> Mix: Capital And Small Letters', + 'Language_Range' => [$Language_Symbol['Upper'], $Language_Symbol['Lower']], + ], + 3 => [ + 'Language_Id' => 3, + 'Language_Name' => 'Numeric', + 'Language_Type' => $Language_Display['Numeric'], + 'Language_Description' => 'Numerical -> Simple', + 'Language_Range' => [$Language_Symbol['Numeric']], + ], + 4 => [ + 'Language_Id' => 4, + 'Language_Name' => 'Alphabet_Upper_Num', + 'Language_Type' => [$Language_Display['Upper'], $Language_Display['Numeric']], + 'Language_Description' => 'Alphabetical And Numerical -> Simple: Capital Letters (Microsoft/Megaupload.com)', + 'Language_Range' => [$Language_Symbol['Upper'], $Language_Symbol['Numeric']], + ], + 5 => [ + 'Language_Id' => 5, + 'Language_Name' => 'Alphabet_Lower_Num', + 'Language_Type' => [$Language_Display['Lower'], $Language_Display['Numeric']], + 'Language_Description' => 'Alphabetical And Numerical -> Simple: Small Letters', + 'Language_Range' => [$Language_Symbol['Lower'], $Language_Symbol['Numeric']], + ], + 6 => [ + 'Language_Id' => 6, + 'Language_Name' => 'Alphabet_Mix_Num', + 'Language_Type' => [$Language_Display['Upper'], $Language_Display['Lower'], $Language_Display['Numeric']], + 'Language_Description' => 'Alphabetical And Numerical -> Mix: Capital And Small Letters', + 'Language_Range' => [$Language_Symbol['Upper'], $Language_Symbol['Lower'], $Language_Symbol['Numeric']], + ], + 7 => [ + 'Language_Id' => 7, + 'Language_Name' => 'Alphabet_Mix_Num_CharShort', + 'Language_Type' => [$Language_Display['Upper'], $Language_Display['Lower'], $Language_Display['Numeric'], $Language_Display['CharShort']], + 'Language_Description' => 'Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Short Special Chars (YouTube.com)', + 'Language_Range' => [$Language_Symbol['Upper'], $Language_Symbol['Lower'], $Language_Symbol['Numeric'], $Language_Symbol['CharShort']], + ], + 8 => [ + 'Language_Id' => 8, + 'Language_Name' => 'Alphabet_Mix_Num_CharLong', + 'Language_Type' => [$Language_Display['Upper'], $Language_Display['Lower'], $Language_Display['Numeric'], $Language_Display['CharLong']], + 'Language_Description' => 'Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Long Special Chars (Safe Password)', + 'Language_Range' => [$Language_Symbol['Upper'], $Language_Symbol['Lower'], $Language_Symbol['Numeric'], $Language_Symbol['CharLong']], + ], + 9 => [ + 'Language_Id' => 9, + 'Language_Name' => 'Alphabet_Mix_Num_CharMix', + 'Language_Type' => [$Language_Display['Upper'], $Language_Display['Lower'], $Language_Display['Numeric'], $Language_Display['CharShort'], $Language_Display['CharLong']], + 'Language_Description' => 'Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Full Special Chars (Safe Password)', + 'Language_Range' => [$Language_Symbol['Upper'], $Language_Symbol['Lower'], $Language_Symbol['Numeric'], $Language_Symbol['CharShort'], $Language_Symbol['CharLong']], + ], + ]; + } + + /** + * Get one language definition by Language_Id. + * + * @return array + */ + public static function ById(int $Language_Id): array + { + $Language = self::Build(); + if (!array_key_exists($Language_Id, $Language)) { + throw new OutOfBoundsException('ERR_PROFILE_NOT_FOUND'); + } + + $Profile = $Language[$Language_Id]; + $Config = CANG_Config::Build(); + + if ( + !isset($Config['Language_Symbol']) || !is_array($Config['Language_Symbol']) || + !isset($Config['Language_Display']) || !is_array($Config['Language_Display']) + ) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + $Symbol_Map = []; + foreach ($Profile['Language_Range'] as $Group) { + $Field_Name = self::FindFieldByGroup($Group, $Config['Language_Symbol']); + $Symbol_Map[$Field_Name] = $Group; + } + + $Type_List = $Profile['Language_Type']; + if (!is_array($Type_List)) { + $Type_List = [$Type_List]; + } + + $Display_Map = []; + foreach ($Type_List as $Display_Value) { + $Field_Name = self::FindFieldByDisplay($Display_Value, $Config['Language_Display']); + $Display_Map[$Field_Name] = $Display_Value; + } + + $Profile['Language_Symbol'] = $Symbol_Map; + $Profile['Language_Display'] = $Display_Map; + + return $Profile; + } + + /** + * @param array $Group + * @param array> $Language_Symbol + */ + private static function FindFieldByGroup(array $Group, array $Language_Symbol): string + { + foreach ($Language_Symbol as $Field_Name => $Symbol_Group) { + if ($Group === $Symbol_Group) { + return $Field_Name; + } + } + + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + /** + * @param array $Language_Display + */ + private static function FindFieldByDisplay(string $Display_Value, array $Language_Display): string + { + foreach ($Language_Display as $Field_Name => $Configured_Value) { + if ($Display_Value === $Configured_Value) { + return $Field_Name; + } + } + + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } +} + +/* +Example usage: + +$Language = CANG_Language::Build(); +$Profile = CANG_Language::ById(7); + + +if (realpath((string) ($_SERVER['SCRIPT_FILENAME'] ?? '')) === __FILE__) { + $Language = CANG_Language::Build(); + echo json_encode($Language, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL; +} +*/ diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Core.php b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Core.php new file mode 100644 index 0000000..7e3c9b9 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Core.php @@ -0,0 +1,338 @@ + */ + private static array $Symbol_List = []; + /** @var array */ + private static array $Symbol_Index = []; + private static bool $Is_Configured = false; + + /** + * Configure core runtime with pure symbol data. + * + * @param array $Symbol_List + * @param array $Symbol_Index + */ + public static function Setup(array $Symbol_List, array $Symbol_Index): void + { + self::$Symbol_List = array_values($Symbol_List); + self::$Symbol_Index = $Symbol_Index; + self::$Is_Configured = true; + } + + /** + * Convert a code string into its numeric id using base-N positional math. + * - Each character is looked up in Symbol_Index. + * - Left-to-right fold: Id = Id * Base + Digit. + * - Throws if any character is not in the configured alphabet. + */ + public static function ConvertTo_Id(string $Code): int + { + self::EnsureReady(); + + $Base = count(self::$Symbol_List); + $Id = 0; + $Length = strlen($Code); + + for ($I = 0; $I < $Length; $I++) { + $Char = $Code[$I]; + $Digit = self::$Symbol_Index[$Char] ?? null; + if ($Digit === null) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + if ($Id > intdiv(PHP_INT_MAX - $Digit, $Base)) { + return PHP_INT_MAX; + } + $Id = ($Id * $Base) + $Digit; + } + + return $Id; + } + + /** + * Convert a numeric id into a fixed-length code string. + * - Repeatedly divides by Base to get digits from right to left. + * - Left-pads with first alphabet symbol when value has fewer digits. + * - Throws when Number cannot fit in the requested Length. + */ + public static function ConvertTo_Code(int $Number, int $Length): string + { + self::EnsureReady(); + self::EnsureLength($Length); + + if ($Number < 0) { + throw new InvalidArgumentException('ERR_NUMBER_REQUIRED'); + } + + $Base = count(self::$Symbol_List); + $Buffer = array_fill(0, $Length, self::$Symbol_List[0]); + $Work = $Number; + + for ($I = $Length - 1; $I >= 0; $I--) { + $Digit = $Work % $Base; + $Buffer[$I] = self::$Symbol_List[$Digit]; + $Work = intdiv($Work, $Base); + } + + if ($Work > 0) { + throw new InvalidArgumentException('ERR_NUMBER_OUT_OF_RANGE'); + } + + return implode('', $Buffer); + } + + /** + * Return the first sequence value for the selected alphabet and length. + * Equivalent to Id(0, Length). + * + * @return array + */ + public static function Beginy(int $Length): array + { + return self::Id(0, $Length); + } + + /** + * Return the previous sequence value for a given code. + * - Resolves current Id first. + * - Subtracts 1 and returns the converted pair. + * - Throws when already at sequence start. + * + * @return array + */ + public static function Previous(string $Code, int $Length): array + { + $Current = self::Current($Code, $Length); + $Prev_Id = (int) $Current['Id'] - 1; + if ($Prev_Id < 0) { + throw new InvalidArgumentException('ERR_SEQUENCE_START'); + } + + return self::Id($Prev_Id, $Length); + } + + /** + * Return the current pair for input code. + * - Converts Code -> Id. + * - Returns both values in unified shape. + * + * @return array + */ + public static function Current(string $Code, int $Length): array + { + self::EnsureLength($Length); + + $Id = self::ConvertTo_Id($Code); + + return [ + 'Code' => $Code, + 'Id' => $Id, + ]; + } + + /** + * Return the next sequence value for a given code. + * - Resolves current Id first. + * - Adds 1 and returns the converted pair. + * - Throws when already at sequence end. + * + * @return array + */ + public static function Next(string $Code, int $Length): array + { + $Current = self::Current($Code, $Length); + $Next_Id = (int) $Current['Id'] + 1; + if ($Next_Id > self::GetMaxNumber($Length)) { + throw new InvalidArgumentException('ERR_SEQUENCE_END'); + } + + return self::Id($Next_Id, $Length); + } + + /** + * Return the last possible sequence value for the given length. + * + * @return array + */ + public static function End(int $Length): array + { + return self::Id(self::GetMaxNumber($Length), $Length); + } + + /** + * Return one random valid sequence value for the given length. + * - Builds random code from configured symbols. + * - Resolves and returns unified current pair. + * + * @return array + */ + public static function Random(int $Length): array + { + self::EnsureReady(); + self::EnsureLength($Length); + + $Max = count(self::$Symbol_List) - 1; + $Code = ''; + for ($I = 0; $I < $Length; $I++) { + $Code .= self::$Symbol_List[random_int(0, $Max)]; + } + + return self::Current($Code, $Length); + } + + /** + * Return sequence pair from explicit numeric id and length. + * + * @return array + */ + public static function Id(int $Number, int $Length): array + { + $Code = self::ConvertTo_Code($Number, $Length); + return self::Current($Code, $Length); + } + + /** + * Guard that core runtime is configured with a usable symbol set. + */ + private static function EnsureReady(): void + { + if (!self::$Is_Configured || count(self::$Symbol_List) < 2) { + throw new InvalidArgumentException('ERR_CORE_NOT_CONFIGURED'); + } + } + + /** + * Guard that requested length is valid for generation/conversion. + */ + private static function EnsureLength(int $Length): void + { + if ($Length < 1) { + throw new InvalidArgumentException('ERR_LENGTH_REQUIRED'); + } + } + + /** + * Calculate maximum id for current Base and requested Length: + * Max = (Base^Length) - 1 + */ + private static function GetMaxNumber(int $Length): int + { + self::EnsureReady(); + self::EnsureLength($Length); + + $Base = count(self::$Symbol_List); + $Max = 1; + for ($I = 0; $I < $Length; $I++) { + $Max *= $Base; + } + + return $Max - 1; + } +} + +/* +Runnable Example: CANG_Core Sequence Demo +Description: +- Configures `CANG_Core` with a small symbol set. +- Demonstrates each sequence mode in practical order. +- Prints one JSON object so developer can inspect each result. + +Step 0) Configure core once with Symbol list and Index map: +$Symbol_List = ['A', 'B', '0', '1', '_']; +$Symbol_Index = [ + 'A' => 0, + 'B' => 1, + '0' => 2, + '1' => 3, + '_' => 4, +]; +// CANG_Core::Setup($Symbol_List, $Symbol_Index); + +Step 1) Beginy(Length): first code of selected alphabet/length. +$Beginy = CANG_Core::Beginy(4); // First + +Step 2) Next(Code, Length): move forward from current code. +$Next_1 = CANG_Core::Next($Beginy['Code'], 4); // Second +$Next_2 = CANG_Core::Next($Next_1['Code'], 4); // Third + +Step 3) Previous(Code, Length): move backward from current code. +$Previous = CANG_Core::Previous($Next_2['Code'], 4); // Back to second + +Step 4) Current(Code, Length): read code + id for any current code. +$Current = CANG_Core::Current($Next_1['Code'], 4); + +Step 5) End(Length): last possible code for selected alphabet/length. +$End = CANG_Core::End(4); + +Step 6) Random(Length): random valid code. +$Random = CANG_Core::Random(4); + +Step 7) Id(Number, Length): build code from explicit id. +$From_Id = CANG_Core::Id(17, 4); +*/ + +/* +// Run this demo only when executing this file directly. +if (realpath((string) ($_SERVER['SCRIPT_FILENAME'] ?? '')) === __FILE__) { + $Symbol_List = ['A', 'B', '0', '1', '_']; + $Symbol_Index = [ + 'A' => 0, + 'B' => 1, + '0' => 2, + '1' => 3, + '_' => 4, + ]; + + CANG_Core::Setup($Symbol_List, $Symbol_Index); + + // 1) Beginy: generate first sequence pair from Id=0. + $Beginy = CANG_Core::Beginy(4); + + // 2) Next: move one step forward from Beginy. + $Next_1 = CANG_Core::Next((string) $Beginy['Code'], 4); + // 2b) Next again: move one more step forward. + $Next_2 = CANG_Core::Next((string) $Next_1['Code'], 4); + + // 3) Previous: move one step backward from Next_2. + $Previous = CANG_Core::Previous((string) $Next_2['Code'], 4); + + // 4) Current: resolve exact Code <-> Id pair for an existing code. + $Current = CANG_Core::Current((string) $Next_1['Code'], 4); + + // 5) End: generate final sequence pair for the same Length. + $End = CANG_Core::End(4); + + // 6) Random: generate one random valid pair. + $Random = CANG_Core::Random(4); + + // 7) Id: generate pair from explicit number. + $From_Id = CANG_Core::Id(17, 4); + + $Runnable_Example_Output = [ + 'How_To_Read' => [ + 'Beginy' => 'First sequence pair (Id=0).', + 'Next_1' => 'One step after Beginy.', + 'Next_2' => 'Two steps after Beginy.', + 'Previous_From_Next_2' => 'Back one step from Next_2.', + 'Current' => 'Resolve current Code -> Id.', + 'End' => 'Last sequence pair for Length.', + 'Random' => 'Random valid pair for Length.', + 'Id_17' => 'Pair generated from Number=17.', + ], + 'Sequence' => [ + 'Beginy' => $Beginy, + 'Next_1' => $Next_1, + 'Next_2' => $Next_2, + 'Previous_From_Next_2' => $Previous, + ], + 'Current' => $Current, + 'End' => $End, + 'Random' => $Random, + 'Id_17' => $From_Id, + ]; + + echo json_encode($Runnable_Example_Output, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL; +} +*/ diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php new file mode 100644 index 0000000..d9d3f3d --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php @@ -0,0 +1,187 @@ + $Options + */ + public function __construct(string $DSN, string $User = '', string $Password = '', array $Options = []) + { + $Default_Options = [ + \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, + \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, + \PDO::ATTR_EMULATE_PREPARES => false, + ]; + + $this->PDO = new \PDO($DSN, $User, $Password, $Options + $Default_Options); + } + + /** + * @param array $Data + */ + public function Insert(string $Table, array $Data): int + { + if ($Data === []) { + throw new \InvalidArgumentException('ERR_INSERT_DATA_REQUIRED'); + } + + $Columns = array_keys($Data); + $Placeholders = array_map(static fn(string $Column): string => ':' . $Column, $Columns); + + $SQL = sprintf( + 'INSERT INTO %s (%s) VALUES (%s)', + $Table, + implode(', ', $Columns), + implode(', ', $Placeholders) + ); + + $Statement = $this->PDO->prepare($SQL); + foreach ($Data as $Column => $Value) { + $Statement->bindValue(':' . $Column, $Value); + } + $Statement->execute(); + + return (int) $this->PDO->lastInsertId(); + } + + /** + * @param array $Where + * @return array> + */ + public function Select(string $Table, array $Where = [], string $Columns = '*', int $Limit = 0): array + { + $SQL = sprintf('SELECT %s FROM %s', $Columns, $Table); + $Params = []; + + if ($Where !== []) { + [$Where_SQL, $Params] = $this->BuildWhere($Where); + $SQL .= ' WHERE ' . $Where_SQL; + } + + if ($Limit > 0) { + $SQL .= ' LIMIT ' . $Limit; + } + + $Statement = $this->PDO->prepare($SQL); + foreach ($Params as $Key => $Value) { + $Statement->bindValue($Key, $Value); + } + $Statement->execute(); + + /** @var array> $Rows */ + $Rows = $Statement->fetchAll(); + return $Rows; + } + + /** + * @param array $Data + * @param array $Where + */ + public function Update(string $Table, array $Data, array $Where): int + { + if ($Data === []) { + throw new \InvalidArgumentException('ERR_UPDATE_DATA_REQUIRED'); + } + if ($Where === []) { + throw new \InvalidArgumentException('ERR_WHERE_REQUIRED'); + } + + $Set_Parts = []; + $Params = []; + foreach ($Data as $Column => $Value) { + $Param_Key = ':set_' . $Column; + $Set_Parts[] = $Column . ' = ' . $Param_Key; + $Params[$Param_Key] = $Value; + } + + [$Where_SQL, $Where_Params] = $this->BuildWhere($Where); + $Params += $Where_Params; + + $SQL = sprintf( + 'UPDATE %s SET %s WHERE %s', + $Table, + implode(', ', $Set_Parts), + $Where_SQL + ); + + $Statement = $this->PDO->prepare($SQL); + foreach ($Params as $Key => $Value) { + $Statement->bindValue($Key, $Value); + } + $Statement->execute(); + + return $Statement->rowCount(); + } + + /** + * @param array $Where + */ + public function Delete(string $Table, array $Where): int + { + if ($Where === []) { + throw new \InvalidArgumentException('ERR_WHERE_REQUIRED'); + } + + [$Where_SQL, $Params] = $this->BuildWhere($Where); + $SQL = sprintf('DELETE FROM %s WHERE %s', $Table, $Where_SQL); + + $Statement = $this->PDO->prepare($SQL); + foreach ($Params as $Key => $Value) { + $Statement->bindValue($Key, $Value); + } + $Statement->execute(); + + return $Statement->rowCount(); + } + + /** + * @param array $Where + * @return array{0:string,1:array} + */ + private function BuildWhere(array $Where): array + { + $Parts = []; + $Params = []; + + foreach ($Where as $Column => $Value) { + $Param_Key = ':where_' . $Column; + $Parts[] = $Column . ' = ' . $Param_Key; + $Params[$Param_Key] = $Value; + } + + return [implode(' AND ', $Parts), $Params]; + } +} + +/* +Simple ISUD Example (Insert, Select, Update, Delete): + +// 1) Create DB instance (SQLite example). +$DB = new CANG_DataBase('sqlite:' . __DIR__ . '/Example.sqlite'); + +// 2) Create a sample table (one-time setup). +$PDO = new PDO('sqlite:' . __DIR__ . '/Example.sqlite'); +$PDO->exec('CREATE TABLE IF NOT EXISTS cang_codes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + code TEXT NOT NULL, + type_id INTEGER NOT NULL +)'); + +// 3) Insert +$New_Id = $DB->Insert('cang_codes', [ + 'code' => 'AB12CD34', + 'type_id' => 7, +]); + +// 4) Select +$Rows = $DB->Select('cang_codes', ['id' => $New_Id]); + +// 5) Update +$Changed = $DB->Update('cang_codes', ['code' => 'ZX98YU76'], ['id' => $New_Id]); + +// 6) Delete +$Removed = $DB->Delete('cang_codes', ['id' => $New_Id]); +*/ diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Driver.php b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Driver.php new file mode 100644 index 0000000..80ca83b --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_Driver.php @@ -0,0 +1,367 @@ +|null */ + private ?array $Selected_Profile = null; + + public function SetLength(int $Length): self + { + if ($Length < 1) { + throw new InvalidArgumentException('ERR_LENGTH_REQUIRED'); + } + $this->Length = $Length; + return $this; + } + + public function SetType(int $Type): self + { + if ($Type < 0) { + throw new InvalidArgumentException('ERR_PROFILE_NOT_FOUND'); + } + $this->Type = $Type; + $this->Selected_Profile = null; + return $this; + } + + public function SetOrder(string $Order_Key): self + { + $this->Order_Key = $Order_Key; + $this->Selected_Profile = null; + return $this; + } + + /** + * Join CANG_ProFile + CANG_Core. + * - Select profile by Type + Order. + * - Setup core with Symbol + Index. + * + * @return array + */ + public function Load(): array + { + if ($this->Selected_Profile === null) { + CANG_ProFile::SetId($this->Type); + $Preview = CANG_ProFile::BuildOrderProfiles(); + if (!isset($Preview['Orders'][$this->Order_Key])) { + $this->Order_Key = 'Order_1'; + } + $this->Selected_Profile = CANG_ProFile::SelectOrder($this->Order_Key); + } + + /** @var array $Symbol_List */ + $Symbol_List = $this->Selected_Profile['Profile']['Symbol']; + /** @var array $Symbol_Index */ + $Symbol_Index = $this->Selected_Profile['Profile']['Index']; + CANG_Core::Setup($Symbol_List, $Symbol_Index); + + return $this->Selected_Profile; + } + + /** + * Validate core internal configuration: + * ValidateCore(Code, Length) -> Length must equal strlen(Code) + * + * @return array + */ + public function ValidateCore(string $Code, int $Length): array + { + if ($Length !== strlen($Code)) { + throw new InvalidArgumentException('ERR_LENGTH_MISMATCH'); + } + + $this->Load(); + if (!$this->IsIntSpaceSafe($Length)) { + if (!$this->IsCodeInSelectedAlphabet($Code)) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + return [ + 'Ok' => true, + 'Status' => 'VALIDATION_PASSED_OVERFLOW_SAFE', + 'Description' => 'Length and alphabet are valid. Roundtrip check skipped due to integer-space limit.', + ]; + } + + $Current = CANG_Core::Current($Code, $Length); + $Check_Code = CANG_Core::ConvertTo_Code((int) $Current['Id'], $Length); + if ($Check_Code !== $Code) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + return [ + 'Ok' => true, + 'Status' => 'VALIDATION_PASSED', + 'Description' => 'Length matches code and conversion is compatible.', + ]; + } + + /** @return array */ + public function Beginy(?int $Length = null): array + { + $Length = $Length ?? $this->Length; + $this->Load(); + $Result = CANG_Core::Beginy($Length); + $Validation = $this->ValidateCore((string) $Result['Code'], $Length); + return $this->BuildUnifiedOutput($Result, $Length, $Validation); + } + + /** @return array */ + public function Previous(string $Code, ?int $Length = null): array + { + $Length = $Length ?? $this->Length; + $Validation = $this->ValidateCore($Code, $Length); + $Result = CANG_Core::Previous($Code, $Length); + return $this->BuildUnifiedOutput($Result, $Length, $Validation); + } + + /** @return array */ + public function Current(string $Code, ?int $Length = null): array + { + $Length = $Length ?? $this->Length; + $Validation = $this->ValidateCore($Code, $Length); + $Result = CANG_Core::Current($Code, $Length); + return $this->BuildUnifiedOutput($Result, $Length, $Validation); + } + + /** @return array */ + public function Next(string $Code, ?int $Length = null): array + { + $Length = $Length ?? $this->Length; + $Validation = $this->ValidateCore($Code, $Length); + $Result = CANG_Core::Next($Code, $Length); + return $this->BuildUnifiedOutput($Result, $Length, $Validation); + } + + /** @return array */ + public function End(?int $Length = null): array + { + $Length = $Length ?? $this->Length; + $this->Load(); + $Result = CANG_Core::End($Length); + $Validation = $this->ValidateCore((string) $Result['Code'], $Length); + return $this->BuildUnifiedOutput($Result, $Length, $Validation); + } + + /** @return array */ + public function Random(?int $Length = null): array + { + $Length = $Length ?? $this->Length; + $this->Load(); + $Result = CANG_Core::Random($Length); + $Validation = $this->ValidateCore((string) $Result['Code'], $Length); + return $this->BuildUnifiedOutput($Result, $Length, $Validation); + } + + /** @return array */ + public function Id(int $Number, ?int $Length = null): array + { + $Length = $Length ?? $this->Length; + $this->Load(); + $Result = CANG_Core::Id($Number, $Length); + $Validation = $this->ValidateCore((string) $Result['Code'], $Length); + return $this->BuildUnifiedOutput($Result, $Length, $Validation); + } + + /** + * Join output in Meta + Profile style. + * + * @param array $Result + * @param array $Validation + * @return array + */ + private function BuildUnifiedOutput(array $Result, int $Length, array $Validation): array + { + $Code = (string) $Result['Code']; + $Id = (int) $Result['Id']; + $Support = $this->AttachCodeSupport($Result, $Length); + $Selected_Meta = (is_array($this->Selected_Profile) && isset($this->Selected_Profile['Meta']) && is_array($this->Selected_Profile['Meta'])) + ? $this->Selected_Profile['Meta'] + : []; + + return [ + 'Meta' => [ + 'Language_Id' => $this->Type, + 'Selected_Order' => $this->Order_Key, + 'Preview_Count' => (int) ($Selected_Meta['Preview_Count'] ?? 0), + 'Available_Order_Id' => (array) ($Selected_Meta['Available_Order_Id'] ?? []), + 'Length' => $Length, + 'Validation_Ok' => (bool) $Validation['Ok'], + 'Validation_Status' => (string) $Validation['Status'], + 'Validation_Description' => (string) $Validation['Description'], + ], + 'Profile' => [ + 'Code_String' => $Code, + 'Code_Id' => $Id, + 'Code_MD5' => (string) $Support['Code_md5'], + 'Code_SHA1' => (string) $Support['Code_sha1'], + 'Code_Base64_Encode' => (string) $Support['Code_base64_encode'], + 'Code_Time' => (int) $Support['Code_time'], + 'Code_Max_Id' => (int) $Support['Code_max_number'], + 'Code_Type' => (int) $Support['Code_type'], + 'Code_Max_Type' => (int) $Support['Code_max_type'], + 'Code_Name' => (string) $Support['Code_name'], + 'Code_Description' => (string) $Support['Code_description'], + ], + ]; + } + + /** + * Attach extra code support fields: + * - md5 + * - sha1 + * - base64_encode + * - timestamp (microseconds, long integer) + * + * @param array $Result + * @return array + */ + private function AttachCodeSupport(array $Result, int $Length): array + { + $Code = (string) $Result['Code']; + $Selected_Meta = (is_array($this->Selected_Profile) && isset($this->Selected_Profile['Meta']) && is_array($this->Selected_Profile['Meta'])) + ? $this->Selected_Profile['Meta'] + : []; + $Result['Code_md5'] = md5($Code); + $Result['Code_sha1'] = sha1($Code); + $Result['Code_base64_encode'] = base64_encode($Code); + $Result['Code_time'] = (int) round(microtime(true) * 1000000); + $Result['Code_max_number'] = $this->GetCodeMaxNumber($Length); + $Result['Code_type'] = $this->Type; + $Result['Code_max_type'] = 9; + $Result['Code_name'] = (string) ($Selected_Meta['Language_Name'] ?? ''); + $Result['Code_description'] = (string) ($Selected_Meta['Language_Description'] ?? ''); + + return $Result; + } + + private function GetCodeMaxNumber(int $Length): int + { + if (!is_array($this->Selected_Profile) || !isset($this->Selected_Profile['Profile']['Symbol']) || !is_array($this->Selected_Profile['Profile']['Symbol'])) { + return 0; + } + + $Base = count($this->Selected_Profile['Profile']['Symbol']); + if ($Base < 2 || $Length < 1) { + return 0; + } + + $Max = 1; + for ($I = 0; $I < $Length; $I++) { + if ($Max > intdiv(PHP_INT_MAX, $Base)) { + return PHP_INT_MAX; + } + $Max *= $Base; + } + + return $Max - 1; + } + + private function IsIntSpaceSafe(int $Length): bool + { + if (!is_array($this->Selected_Profile) || !isset($this->Selected_Profile['Profile']['Symbol']) || !is_array($this->Selected_Profile['Profile']['Symbol'])) { + return false; + } + + $Base = count($this->Selected_Profile['Profile']['Symbol']); + if ($Base < 2 || $Length < 1) { + return false; + } + + $Max = 1; + for ($I = 0; $I < $Length; $I++) { + if ($Max > intdiv(PHP_INT_MAX, $Base)) { + return false; + } + $Max *= $Base; + } + + return true; + } + + private function IsCodeInSelectedAlphabet(string $Code): bool + { + if (!is_array($this->Selected_Profile) || !isset($this->Selected_Profile['Profile']['Index']) || !is_array($this->Selected_Profile['Profile']['Index'])) { + return false; + } + + /** @var array $Index */ + $Index = $this->Selected_Profile['Profile']['Index']; + $Length = strlen($Code); + for ($I = 0; $I < $Length; $I++) { + if (!array_key_exists($Code[$I], $Index)) { + return false; + } + } + + return true; + } +} + +/* +Usage Example: CANG_Driver Methods + +Description: +- SetLength(Length): set default code length for generation methods. +- SetType(Type): select language profile id (0..9 in current language config). +- SetOrder(Order_Key): select one generated profile order (Order_1, Order_2, ...). +- Load(): resolve selected profile and configure CANG_Core. +- ValidateCore(Code, Length): validate input code against internal runtime alphabet and length. +- Beginy(Length?): get first sequence code/id for selected config. +- Previous(Code, Length?): get previous sequence code/id. +- Current(Code, Length?): resolve id for a given code. +- Next(Code, Length?): get next sequence code/id. +- End(Length?): get last sequence code/id. +- Random(Length?): get random valid code/id. +- Id(Number, Length?): get code/id from explicit numeric id. +*/ + +/* +// Runnable example (execute this file directly) +if (realpath((string) ($_SERVER['SCRIPT_FILENAME'] ?? '')) === __FILE__) { + $Driver = new CANG_Driver(); + + // Step 1: Runtime setup. + $Driver->SetLength(8); // default Length for methods when Length is omitted + $Driver->SetType(7); // profile id: Alphabet_Mix_Num_CharShort + $Driver->SetOrder('Order_1'); // selected order from generated profile permutations + $Selected_Profile = $Driver->Load(); + + // Step 2: Generate first value, then move through sequence. + $Beginy = $Driver->Beginy(); // first code/id + $Next = $Driver->Next((string) $Beginy['Profile']['Code_String']); + $Current = $Driver->Current((string) $Next['Profile']['Code_String']); + $Previous = $Driver->Previous((string) $Current['Profile']['Code_String']); + $End = $Driver->End(); + $Random = $Driver->Random(); + + // Step 3: Generate by explicit numeric id. + $By_Id = $Driver->Id(12345); + + // Step 4: Explicit validation example. + $Validation = $Driver->ValidateCore((string) $Beginy['Profile']['Code_String'], 8); + + echo json_encode([ + 'Selected_Profile' => $Selected_Profile, + 'Beginy' => $Beginy, + 'Next' => $Next, + 'Current' => $Current, + 'Previous' => $Previous, + 'End' => $End, + 'Random' => $Random, + 'By_Id' => $By_Id, + 'Validation' => $Validation, + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL; +} +*/ diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_ProFile.php b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_ProFile.php new file mode 100644 index 0000000..a18ed3e --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_ProFile.php @@ -0,0 +1,325 @@ +> + */ + public static function LoadConfig(): array + { + return CANG_Language::Build(); + } + + public static function SetId(int $Language_Id): void + { + if ($Language_Id < 0) { + throw new InvalidArgumentException('ERR_PROFILE_NOT_FOUND'); + } + + self::$Language_Id = $Language_Id; + self::$Preview_Profile = null; + self::$Selected_Profile = null; + } + + /** + * Expose selected profile field names (array keys). + * + * @return array + */ + public static function ExposeValueArrayNames(): array + { + if (self::$Language_Id === null) { + throw new InvalidArgumentException('ERR_PROFILE_NOT_FOUND'); + } + + $Profile = CANG_Language::ById(self::$Language_Id); + return array_keys($Profile); + } + + /** + * Build all possible order profiles for Language_Range and Language_Type together. + * + * If one field exists -> fixed order. + * If multiple fields exist -> all permutations. + * + * @return array + */ + public static function BuildOrderProfiles(): array + { + if (self::$Language_Id === null) { + throw new InvalidArgumentException('ERR_PROFILE_NOT_FOUND'); + } + + $Profile = CANG_Language::ById(self::$Language_Id); + if ( + !isset($Profile['Language_Symbol']) || !is_array($Profile['Language_Symbol']) || + !isset($Profile['Language_Display']) || !is_array($Profile['Language_Display']) + ) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + $Language_Symbol = $Profile['Language_Symbol']; + $Language_Display = $Profile['Language_Display']; + + $Field_Names = array_values( + array_intersect(array_keys($Language_Symbol), array_keys($Language_Display)) + ); + + if (count($Field_Names) === 0) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + if (count($Field_Names) > self::MAX_BASE_FIELDS) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + $Orders = []; + if (count($Field_Names) === 1) { + $Order_Field_List = $Field_Names; + $Join = self::BuildJoinedRangeAndIndex([$Language_Symbol[$Order_Field_List[0]]]); + $Orders['Order_1'] = [ + 'Field_Order' => $Order_Field_List, + 'Language_Range' => [$Language_Symbol[$Order_Field_List[0]]], + 'Language_Type' => [$Language_Display[$Order_Field_List[0]]], + 'Language_Symbol_Build' => $Join['Language_Symbol_Build'], + 'Language_Symbol_Index' => $Join['Language_Symbol_Index'], + ]; + + self::$Preview_Profile = [ + 'Language_Id' => self::$Language_Id, + 'Order_Mode' => 'Fixed', + 'Order_Total' => 1, + 'Orders' => $Orders, + ]; + self::$Selected_Profile = null; + + return self::$Preview_Profile; + } + + $Permutations = self::BuildSequentialFieldOrders($Field_Names); + $Order_Index = 1; + + foreach ($Permutations as $Field_Order) { + $Ordered_Range = []; + $Ordered_Type = []; + + foreach ($Field_Order as $Field_Name) { + $Ordered_Range[] = $Language_Symbol[$Field_Name]; + $Ordered_Type[] = $Language_Display[$Field_Name]; + } + $Join = self::BuildJoinedRangeAndIndex($Ordered_Range); + + $Orders['Order_' . $Order_Index] = [ + 'Field_Order' => $Field_Order, + 'Language_Range' => $Ordered_Range, + 'Language_Type' => $Ordered_Type, + 'Language_Symbol_Build' => $Join['Language_Symbol_Build'], + 'Language_Symbol_Index' => $Join['Language_Symbol_Index'], + ]; + $Order_Index++; + } + + self::$Preview_Profile = [ + 'Language_Id' => self::$Language_Id, + 'Order_Mode' => 'Permutations', + 'Order_Total' => count($Orders), + 'Orders' => $Orders, + ]; + self::$Selected_Profile = null; + + return self::$Preview_Profile; + } + + /** + * Select one order from preview and return selected profile output. + * + * @return array + */ + public static function SelectOrder(string $Order_Key): array + { + if (self::$Preview_Profile === null) { + throw new InvalidArgumentException('ERR_PROFILE_PREVIEW_REQUIRED'); + } + + $Profiles = self::$Preview_Profile; + if (!isset($Profiles['Orders']) || !is_array($Profiles['Orders'])) { + throw new InvalidArgumentException('ERR_INVALID_ALPHABET'); + } + + $Orders = $Profiles['Orders']; + if (!array_key_exists($Order_Key, $Orders)) { + throw new InvalidArgumentException('ERR_PROFILE_NOT_FOUND'); + } + + $Selected = $Orders[$Order_Key]; + $Language_Profile = CANG_Language::ById((int) $Profiles['Language_Id']); + + self::$Selected_Profile = [ + 'Language_Id' => $Profiles['Language_Id'], + 'Order_Mode' => $Profiles['Order_Mode'], + 'Selected_Order' => $Order_Key, + 'Selected_Data' => $Selected, + ]; + self::$Preview_Profile = null; + + return [ + 'Meta' => [ + 'Language_Id' => self::$Selected_Profile['Language_Id'], + 'Language_Name' => (string) ($Language_Profile['Language_Name'] ?? ''), + 'Language_Description' => (string) ($Language_Profile['Language_Description'] ?? ''), + 'Selected_Order' => self::$Selected_Profile['Selected_Order'], + 'Preview_Count' => $Profiles['Order_Total'], + 'Available_Order_Id' => array_keys($Orders), + ], + 'Profile' => [ + 'Order' => $Selected['Field_Order'], + 'Symbol' => $Selected['Language_Symbol_Build'], + 'Index' => $Selected['Language_Symbol_Index'], + ], + ]; + } + + /** + * @param array $Fields + * @return array> + */ + private static function BuildSequentialFieldOrders(array $Fields): array + { + $Count = count($Fields); + if ($Count <= 1) { + return [$Fields]; + } + + $Permutations = []; + $Indices = range(0, $Count - 1); + + while (true) { + $Order = []; + foreach ($Indices as $Index) { + $Order[] = $Fields[$Index]; + } + $Permutations[] = $Order; + + if (!self::NextPermutation($Indices)) { + break; + } + } + + return $Permutations; + } + + /** + * Advance integer sequence to next lexicographic permutation. + * + * @param array $Values + */ + private static function NextPermutation(array &$Values): bool + { + $N = count($Values); + $I = $N - 2; + while ($I >= 0 && $Values[$I] >= $Values[$I + 1]) { + $I--; + } + if ($I < 0) { + return false; + } + + $J = $N - 1; + while ($Values[$J] <= $Values[$I]) { + $J--; + } + + [$Values[$I], $Values[$J]] = [$Values[$J], $Values[$I]]; + + $Left = $I + 1; + $Right = $N - 1; + while ($Left < $Right) { + [$Values[$Left], $Values[$Right]] = [$Values[$Right], $Values[$Left]]; + $Left++; + $Right--; + } + + return true; + } + + /** + * Join ordered Language_Range groups into one unique array and build index map. + * + * @param array> $Ordered_Range + * @return array + */ + private static function BuildJoinedRangeAndIndex(array $Ordered_Range): array + { + $Joined = []; + $Seen = []; + + foreach ($Ordered_Range as $Group) { + foreach ($Group as $Value) { + if (!isset($Seen[$Value])) { + $Seen[$Value] = true; + $Joined[] = $Value; + } + } + } + + $Index = []; + foreach ($Joined as $Position => $Value) { + $Index[$Value] = $Position; + } + + return [ + 'Language_Symbol_Build' => $Joined, + 'Language_Symbol_Index' => $Index, + ]; + } +} + +/* +Complete example: + +1) Select profile id +2) Build preview orders +3) Select one order key +4) Get selected output + +CANG_ProFile::SetId(7); +$Preview_Profiles = CANG_ProFile::BuildOrderProfiles(); +$Order_Key = 'Order_2'; //<- Here Select Number According To Maximum Allowed Id +if (!isset($Preview_Profiles['Orders'][$Order_Key])) { + $Order_Key = 'Order_1'; //<- Only FallBack If Key Not Exists +} +$Selected_Output = CANG_ProFile::SelectOrder($Order_Key); + + +if (realpath((string) ($_SERVER['SCRIPT_FILENAME'] ?? '')) === __FILE__) { + $Selected_Id = 9; + CANG_ProFile::SetId($Selected_Id); + + // Step 1: Preview possible orders. + $Preview_Profiles = CANG_ProFile::BuildOrderProfiles(); + //print_r($Preview_Profiles); + $Order_Key = 'Order_49'; + if (!isset($Preview_Profiles['Orders'][$Order_Key])) { + $Order_Key = 'Order_1'; + } + + // Step 2: Select one order. Preview state is cleared after this call. + $Selected_Output = CANG_ProFile::SelectOrder($Order_Key); + + echo json_encode([ + 'Selected_Output' => $Selected_Output, + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL; + +} +*/ diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_MS_G.php b/v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Controller.php similarity index 100% rename from v.0.5.FinallVersion/Base_CANG_Generators/CANG_MS_G.php rename to v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Controller.php diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Module.php b/v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Module.php new file mode 100644 index 0000000..e69de29 diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Viewer.php b/v.0.5.FinallVersion/Base_CANG/CANG_MVC/CANG_Viewer.php new file mode 100644 index 0000000..e69de29 diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID.php new file mode 100644 index 0000000..4e2c033 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID.php @@ -0,0 +1,23 @@ +SetLength(8); + +// 2) Select profile id (Language_Id). +$Driver->SetType(5); + +// 3) Optional: select order key when multiple profile permutations are available. +$Driver->SetOrder('Order_1'); + +// 4) Load selected profile into core runtime. +$Driver->Load(); + +// 5) Generate code by explicit numeric Id. +$Return = $Driver->Id(249996); + +print_r($Return); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php new file mode 100644 index 0000000..523cce5 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php @@ -0,0 +1,24 @@ +SetLength(8); + +// 2) Select profile id (Language_Id). +$Driver->SetType(5); + +// 3) Optional: select order key when multiple profile permutations are available. +$Driver->SetOrder('Order_1'); + +// 4) Load selected profile into core runtime. +$Driver->Load(); + +// 5) Generate code by explicit numeric Id. +$Return = $Driver->Id(249996); + +header('Content-Type: application/json'); +echo json_encode($Return, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random.php new file mode 100644 index 0000000..8e58067 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random.php @@ -0,0 +1,23 @@ +SetLength(8); + +// 2) Select profile id (Language_Id). +$Driver->SetType(5); + +// 3) Optional: select order key when multiple profile permutations are available. +$Driver->SetOrder('Order_1'); + +// 4) Load selected profile into core runtime. +$Driver->Load(); + +// 5) Generate one random code. +$Return = $Driver->Random(); + +print_r($Return); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php new file mode 100644 index 0000000..f70bfd6 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php @@ -0,0 +1,24 @@ +SetLength(8); + +// 2) Select profile id (Language_Id). +$Driver->SetType(5); + +// 3) Optional: select order key when multiple profile permutations are available. +$Driver->SetOrder('Order_1'); + +// 4) Load selected profile into core runtime. +$Driver->Load(); + +// 5) Generate one random code. +$Return = $Driver->Random(); + +header('Content-Type: application/json'); +echo json_encode($Return, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String.php new file mode 100644 index 0000000..4cef477 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String.php @@ -0,0 +1,26 @@ +SetLength(8); + +// 2) Select profile id (Language_Id). +$Driver->SetType(5); + +// 3) Optional: select order key when multiple profile permutations are available. +$Driver->SetOrder('Order_1'); + +// 4) Load selected profile into core runtime. +$Driver->Load(); + +// 5) Generate simple string by sequence start (not random). +$Return = $Driver->Beginy(); + +// 6) Generate next simple string from previous output. +$Return = $Driver->Next((string) $Return[1]['Profile']['Code_String']); + +print_r($Return); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String_JSON.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String_JSON.php new file mode 100644 index 0000000..e66ed2b --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Generate_String_JSON.php @@ -0,0 +1,27 @@ +SetLength(8); + +// 2) Select profile id (Language_Id). +$Driver->SetType(5); + +// 3) Optional: select order key when multiple profile permutations are available. +$Driver->SetOrder('Order_1'); + +// 4) Load selected profile into core runtime. +$Driver->Load(); + +// 5) Generate simple string by sequence start (not random). +$Return = $Driver->Beginy(); + +// 6) Generate next simple string from previous output. +$Return = $Driver->Next((string) $Return['Profile']['Code_String']); + +header('Content-Type: application/json'); +echo json_encode($Return, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php new file mode 100644 index 0000000..a6c8022 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php @@ -0,0 +1,26 @@ +SetLength(25); +$Driver->SetType(4); +$Driver->SetOrder('Order_1'); +$Driver->Load(); + +// Generate by numeric Id. +$Result = $Driver->Id(249996); + +// Format code as XXXXX-XXXXX-XXXXX-XXXXX-XXXXX +$Raw_Code = (string) ($Result['Profile']['Code_String'] ?? ''); +$Groups = str_split($Raw_Code, 5); +$Formatted_Code = implode('-', $Groups); + +$Result['Profile']['Code_String_Formatted'] = $Formatted_Code; + +print_r($Result); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php new file mode 100644 index 0000000..dbcc061 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php @@ -0,0 +1,27 @@ +SetLength(25); +$Driver->SetType(4); +$Driver->SetOrder('Order_1'); +$Driver->Load(); + +// Generate by numeric Id. +$Result = $Driver->Id(249996); + +// Format code as XXXXX-XXXXX-XXXXX-XXXXX-XXXXX +$Raw_Code = (string) ($Result['Profile']['Code_String'] ?? ''); +$Groups = str_split($Raw_Code, 5); +$Formatted_Code = implode('-', $Groups); + +$Result['Profile']['Code_String_Formatted'] = $Formatted_Code; + +header('Content-Type: application/json'); +echo json_encode($Result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php new file mode 100644 index 0000000..addc70e --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php @@ -0,0 +1,26 @@ +SetLength(25); +$Driver->SetType(4); +$Driver->SetOrder('Order_1'); +$Driver->Load(); + +// Generate random code. +$Result = $Driver->Random(); + +// Format code as XXXXX-XXXXX-XXXXX-XXXXX-XXXXX +$Raw_Code = (string) ($Result['Profile']['Code_String'] ?? ''); +$Groups = str_split($Raw_Code, 5); +$Formatted_Code = implode('-', $Groups); + +$Result['Profile']['Code_String_Formatted'] = $Formatted_Code; + +print_r($Result); diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php new file mode 100644 index 0000000..19482a3 --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG/CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php @@ -0,0 +1,27 @@ +SetLength(25); +$Driver->SetType(4); +$Driver->SetOrder('Order_1'); +$Driver->Load(); + +// Generate random code. +$Result = $Driver->Random(); + +// Format code as XXXXX-XXXXX-XXXXX-XXXXX-XXXXX +$Raw_Code = (string) ($Result['Profile']['Code_String'] ?? ''); +$Groups = str_split($Raw_Code, 5); +$Formatted_Code = implode('-', $Groups); + +$Result['Profile']['Code_String_Formatted'] = $Formatted_Code; + +header('Content-Type: application/json'); +echo json_encode($Result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); diff --git a/v.0.5.FinallVersion/Base_CANG_CommandAI.ExternalRules.md b/v.0.5.FinallVersion/Base_CANG_CommandAI.ExternalRules.md new file mode 100644 index 0000000..970bb1f --- /dev/null +++ b/v.0.5.FinallVersion/Base_CANG_CommandAI.ExternalRules.md @@ -0,0 +1,431 @@ +--- +Title: CANG Project Definition (External Rewrite) +Source: Rewrite of Base_CANG_CommandAI.md +Status: Development Ready +--- + +## 1) Purpose +CANG (Complex Alpha Numeric Generator) is a PHP utility for generating and converting alphanumeric codes. +This document defines behavior contracts; implementation details may vary. +Documentation style rule (shareability): use one arrow style `A -> B` for mappings/flows and sentence case for descriptive lines across all sections. +Project description: The Complex Alpha Numeric Generator (CANG) is a PHP-based utility +designed to produce highly customizable alphanumeric strings for authentication systems, +token creation, unique identifiers, and data-randomization workflows. + +Built for developers who need both flexibility and reliability, CANG supports layered +configuration options including character-set selection, entropy tuning, pattern +enforcement, and optional cryptographic strengthening. + +CANG's architecture emphasizes modularity and clean integration. It can operate as a +standalone function, a reusable class, or a plug-in component within larger PHP +applications. + +Its deterministic configuration model ensures repeatable behavior when needed, while still +offering strong randomness for security-sensitive contexts. + +Whether you are generating session keys, invitation codes, randomized filenames, or +structured alphanumeric sequences, CANG provides a robust, developer-friendly foundation +that adapts to a wide range of project requirements. + +Primary capabilities: +- Generate and convert by mode (`Beginy`, `Previous`, `Current`, `Next`, `End`, `Random`, `Id`) +- Return both `Code` and `Id` for conversion-aware operations +- Use selectable language profiles (character sets) +- Support deterministic and random workflows + +## 2) Config Architecture +Core file design: +- `CANG_Config` -> complex configuration array that defines all language fundamentals. +- `CANG_Language` -> loads config data and prepares sortable language structures. +- `CANG_ProFile` -> imports language definitions from `CANG_Language`, selects language/profile, and applies developer-defined order. +- `CANG_Core` -> uses selected profile/order to run generation and conversion only. + +Section-to-Unit mapping: +- `CANG_Config` -> Sections `2`, `3`, `4`, `5` +- `CANG_Language` -> Sections `4`, `5` +- `CANG_ProFile` -> Sections `5`, `6` +- `CANG_Core` -> Sections `6`, `7`, `8`, `10`, `11`, `12` + +Core load flow: +- `Config -> Language -> ProFile -> Core` + +## 3) Fundamental Config Symbols +`Language_Symbol` definitions: +- `Upper -> range('A','Z')` +- `Lower -> range('a','z')` +- `Numeric -> range('0','9')` +- `CharShort -> str_split('_-')` +- `CharLong -> str_split('#$%&+-@')` +- Core Language_Symbol rule: each `Language_Symbol` name (example: `CharLong`) must be followed by a defined range. +- Core range-constructor rule: both `range(...)` and `str_split(...)` are valid ways to create symbol ranges. + +Regex-safe note: +- Applies only to true regex-processing patterns; it does not apply to `Language_Type` references or `Language_Display` values. + + +## 4) Canonical Language Definitions +Each language profile is one complete record. + +Strict-name scopes: +- Core Strict_Name rule (profile record fields only): `Language_Id`, `Language_Name`, `Language_Type`, `Language_Description`, `Language_Range`. +- Core Strict_Name rule (language config maps): `Language_Symbol`, `Language_Display`. +- Core Strict_Name permanent rule: these exact key names are fixed and must be remembered/kept forever for compatibility. + +Required profile fields: +- `Language_Id` (int) +- `Language_Name` (string) +- `Language_Type` (ordered `Language_Display` references) +- `Language_Description` (string) +- `Language_Range` (ordered symbol groups) + +Language display map: +- `Language_Display['Upper'] = '[A-Z]'` +- `Language_Display['Lower'] = '[a-z]'` +- `Language_Display['Numeric'] = '[0-9]'` +- `Language_Display['CharShort'] = '[-_]'` +- `Language_Display['CharLong'] = '[#$%&+-@]'` +- Core Language_Type value rule: every `Language_Type` item must be a `Language_Display['Field_Name']` reference. +- Core Language_Type shape rule: input may be single reference or list of references (hybrid input allowed). +- Core Language_Type runtime rule: always normalize to list form internally before processing. +- Core Language_Type ordering rule: reordering applies only when normalized list has more than one item; one item is fixed-order (no-op). +- Core Language_Type reference rule: every referenced `Language_Display['Field_Name']` key must exist in `Language_Display`. +- Core Language_Type validation rule: regex validity/escaping is not required for `Language_Type` items because they are references, not regex patterns. +- Core Language_Type format examples: `Language_Type: Language_Display['Upper']` or `Language_Type: [Language_Display['Upper'], Language_Display['Lower']]`. + +Language symbol map: +- `Language_Symbol` is defined through `Language_Range` references as `Language_Symbol[Name]`. +- Core Language_Range rule: `Language_Range` holds the range of symbols. +- Core Language_Range ordering rule: ordering is possible only when `Language_Range` contains more than one key symbol name. +- If `Language_Range` contains only one key symbol name, ordering is not applicable (no-op) and the single order is fixed. + +Canonical profiles: +1. `Language_Id: 0` +- `Language_Name: Alphabet_Upper` +- `Language_Type: Language_Display['Upper']` +- `Language_Description: Alphabetical -> Simple: Capital Letters` +- `Language_Range: [Language_Symbol[Upper]]` + +2. `Language_Id: 1` +- `Language_Name: Alphabet_Lower` +- `Language_Type: Language_Display['Lower']` +- `Language_Description: Alphabetical -> Simple: Small Letters` +- `Language_Range: [Language_Symbol[Lower]]` + +3. `Language_Id: 2` +- `Language_Name: Alphabet_Mix` +- `Language_Type: [Language_Display['Upper'], Language_Display['Lower']]` +- `Language_Description: Alphabetical -> Mix: Capital And Small Letters` +- `Language_Range: [Language_Symbol[Upper], Language_Symbol[Lower]]` + +4. `Language_Id: 3` +- `Language_Name: Numeric` +- `Language_Type: Language_Display['Numeric']` +- `Language_Description: Numerical -> Simple` +- `Language_Range: [Language_Symbol[Numeric]]` + +5. `Language_Id: 4` +- `Language_Name: Alphabet_Upper_Num` +- `Language_Type: [Language_Display['Upper'], Language_Display['Numeric']]` +- `Language_Description: Alphabetical And Numerical -> Simple: Capital Letters (Microsoft/Megaupload.com)` +- `Language_Range: [Language_Symbol[Upper], Language_Symbol[Numeric]]` + +6. `Language_Id: 5` +- `Language_Name: Alphabet_Lower_Num` +- `Language_Type: [Language_Display['Lower'], Language_Display['Numeric']]` +- `Language_Description: Alphabetical And Numerical -> Simple: Small Letters` +- `Language_Range: [Language_Symbol[Lower], Language_Symbol[Numeric]]` + +7. `Language_Id: 6` +- `Language_Name: Alphabet_Mix_Num` +- `Language_Type: [Language_Display['Upper'], Language_Display['Lower'], Language_Display['Numeric']]` +- `Language_Description: Alphabetical And Numerical -> Mix: Capital And Small Letters` +- `Language_Range: [Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric]]` + +8. `Language_Id: 7` +- `Language_Name: Alphabet_Mix_Num_CharShort` +- `Language_Type: [Language_Display['Upper'], Language_Display['Lower'], Language_Display['Numeric'], Language_Display['CharShort']]` +- `Language_Description: Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Short Special Chars (YouTube.com)` +- `Language_Range: [Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric], Language_Symbol[CharShort]]` + +9. `Language_Id: 8` +- `Language_Name: Alphabet_Mix_Num_CharLong` +- `Language_Type: [Language_Display['Upper'], Language_Display['Lower'], Language_Display['Numeric'], Language_Display['CharLong']]` +- `Language_Description: Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Long Special Chars (Safe Password)` +- `Language_Range: [Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric], Language_Symbol[CharLong]]` + +10. `Language_Id: 9` +- `Language_Name: Alphabet_Mix_Num_CharMix` +- `Language_Type: [Language_Display['Upper'], Language_Display['Lower'], Language_Display['Numeric'], Language_Display['CharShort'], Language_Display['CharLong']]` +- `Language_Description: Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Full Special Chars (Safe Password)` +- `Language_Range: [Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric], Language_Symbol[CharShort], Language_Symbol[CharLong]]` + +## 5) Language Order and Defaults +`CANG_ProFile` must support language selection and order override. + +Order contract: +- Core Language_Order directional rule: `Language_Order` is AI-directional description for selected-language mapping and reorder behavior. +- `Language_Order(Same Values According To Selected Language_Id) -> ReOrderAble Fields By Developer/User Input` +- Core directional-term rule: `ReOrderAble` is intentional AI directional description and must be kept as defined. + +Selection contract: +- `Default_Language -> Language_Id` +- `Default_Order` must be built only from `Language_Range` symbols of the selected `Default_Language`. +- `CANG_ProFile` must include the selected language definition imported from `CANG_Language` and order only those available symbols. +- Global template example (config-level): `[Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric], Language_Symbol[CharShort], Language_Symbol[CharLong]]`. + +Custom order example: +- `Default_Language -> Language_Id` +- `Default_Order -> [Language_Symbol[CharLong], Language_Symbol[CharShort], Language_Symbol[Numeric], Language_Symbol[Lower], Language_Symbol[Upper]]` (apply only if these symbols exist in selected language definition). + +Compiled alphabet rule: +- `Compiled_Alphabet` = concatenation of active `Language_Range` groups in selected order. +- Duplicate characters must be removed while preserving first occurrence. +- Alphabet size must be `>= 2`. + +## 6) Length Rules +- `Length` is mandatory for generated code output. +- If `Length` is missing, throw `ERR_LENGTH_REQUIRED`. +- `Length` must be a positive integer. +- Never accept `0`; throw `ERR_INVALID_LENGTH`. +- Absolute minimum allowed by engine is `1`. +- `Min_Length = 8` is a recommended default policy example, not a hard engine floor. +- If project policy sets a higher minimum (example `8`), values below that policy minimum must throw `ERR_INVALID_CODE_LENGTH`. +- For code-input modes, `strlen(Code)` must match `Length`; otherwise throw `ERR_LENGTH_MISMATCH`. + +## 7) Mode Contracts +All modes run against one selected profile and one compiled alphabet. + +Mode definition order must remain (documentation/reference order only, not required runtime invocation order): +1. `Beginy` +2. `Previous` +3. `Current` +4. `Next` +5. `End` +6. `Random` +7. `Id` + +Canonical mode names (keep as defined): +1. Beginy +2. Previous +3. Current +4. Next +5. End +6. Random +7. Id +- Core naming rule: capitalize the first letter of Variables and Methods in rules/examples. +- Core native-function rule: native PHP functions must keep their original names/casing (example: `strlen`, `random_int`). +- Core native-variable rule: if a native variable/constant is defined in capital letters, keep it exactly as native-defined. +- Method names use `Beginy/Previous/Current/Next/End/Random/Id`, while validation mode tokens use `BEGINY/PREVIOUS/CURRENT/NEXT/END/RANDOM/ID`. +- Variable style uses `Code/Id/Length/Number` and `$Code/$Id/$Length/$Number`. +- Capitalized Variables/Methods in this document are naming conventions for readability. + +Unified return shape for these modes: +- `{ Code: string, Id: int }` +- Mini return example: `{Code:"AAAAAAAB", Id:1}` + +Return contracts: +- `Beginy(Length)` -> `{Code, Id}` +- `Previous(Code, Length)` -> `{Code, Id}` +- `Current(Code, Length)` -> `{Code, Id}` +- `Next(Code, Length)` -> `{Code, Id}` +- `End(Length)` -> `{Code, Id}` +- `Random(Length)` -> `{Code, Id}` +- `Id(Number, Length)` -> `{Code, Id}` + +Quick call block: +- `Beginy(Length)` +- `Previous(Code, Length)` +- `Id(Number, Length)` +- `Random(Length)` + +Rules: +- For every mode above, `Length` must be explicitly specified. +- If missing, throw `ERR_LENGTH_REQUIRED`. +- Core validation method rule: `ValidateCore(Length, Code, Id): {Ok: bool, Status: string, Description: string}` is moved out of `CANG_Core` and currently on hold for a separate validation file. +- Core existence method rule: `CANG_Core` must expose `ExistenceCheck(Length, Code, Id): {Exists: bool, Status: string, Reason: string, Description: string}`. +- Core generator helper rules: +- `ConvertTo_Code(Id, Length): Code` +- `ConvertTo_Id(Code, Length): Id` +- `Generate_ByRandomCode(Length): {Code, Id}` +- Internal loop rule for retry/fallback paths: `For (Step = 0; Step < Limit; Step++)`. +- Canonical Id route rule (single source of truth) for public `Id(Number, Length)`: +- `1) Map Number -> Id` and generate `{Code, Id}`. +- `2) Pass output to `Current(Code, Length)` (validation is handled by external validator when enabled). +- `3) Run `ExistenceCheck`. +- Mapping example: +- `// Method inputs: $Number, $Length` +- `// Step 1: Apply canonical Id route step (map Number -> Id and generate {Code, Id}).` +- `// Step 2: Pass generated output to Current(Code, Length).` +- Pseudo-code example: +```php +$Output = Id($Number, $Length); // {Code, Id} +Current($Output['Code'], $Length); // external validation (on hold) can run before/after this step +ExistenceCheck($Length, $Output['Code'], $Output['Id']); +``` +- Validation hold rule: `ValidateCore` is external and on hold; `CANG_Core` does not execute it. +- External validator target behavior (on hold): check `strlen(Code) == Length` (when `Code` is provided), then validate `Code` and `Id` conversion compatibility. +- Clean flow contract: +- `1) Current(...)` runs core conversion flow. +- `2) External validation (on hold)`: run before/after `Current(...)` as policy requires. +- `3) If invalid`: throw mapped `ERR_*`. +- `4) If valid`: return success info (or nothing). +- `5) API layer`: catch exception and format `{Ok:false,Error,Description}`. +- Developer success example: `{Ok:true,Status:"VALIDATION_PASSED",Description:"Inputs are valid for the selected mode."}` +- Developer input table (public modes): +- `BEGINY` -> required: `Length` +- `PREVIOUS` -> required: `Length`, `Code` +- `CURRENT` -> required: `Length`, `Code` +- `NEXT` -> required: `Length`, `Code` +- `END` -> required: `Length` +- `RANDOM` -> required: `Length` +- `ID` -> required: `Length`, `Number` +- `Reverse` is internal-only compatibility alias helper, not a public validation mode. +- Core reverse-usage rule: `Reverse` must not be used in canonical execution flow diagrams. +- Core reverse-routing rule: if implemented, `Reverse` only routes to `ConvertTo_Id` or `ConvertTo_Code` based on input type; it must not define separate conversion logic. +- `Current` does not perform reverse conversion because it represents the same input `Code` in the current sequence position. +- `Current` must return the exact current `{Code, Id}` pair for sequencing accuracy (`Code`, `Length`, `Id`); length/input validation is handled by external validator (on hold). +- Core `Current` rule: input `Code` is treated as current-sequence reference by default. +- `Current` must not execute validation internally while validation is on hold outside `CANG_Core`. +- `Current` is the reference state used to define `Previous`, `Next`, `Beginy`, and `End` sequence behavior. +- Core conversion rule: `Id` is used for conversion at any `Sequence_OP` (directly or indirectly). +- Core sequencing anchor rule: `Beginy` is the first output point that defines sequence start context. +- Core Beginy rule: `Beginy` must internally produce initial `Code` from `Length`, then use that produced `Code` as the input context for `Current` and validation flow. +- After anchor, sequencing methods use `{Code, Length}` context for progression (`Previous(Code, Length)` / `Next(Code, Length)` compatibility model). +- Core execution reference rule for `Previous/Next` (runtime-aligned): +- `1) (Previous(Code, Length) | Next(Code, Length)) -> Current(Code, Length)`. +- `2) Current(Code, Length) -> ConvertTo_Id -> Sequence_OP -> ExistenceCheck`. +- Validation is external/on hold and does not run inside `Current`. +- Internal chaining rule: `Previous` and `Next` resolve current position first through `Current` (internally using `ConvertTo_Id` for position resolution), then adjust `Id` and generate final output through internal `ConvertTo_Code`. +- Exact algorithm for `Previous/Next`: +- `1) $PrevNumber = Current(Code, Length).Id - 1`, then `$PrevCode = ConvertTo_Code($PrevNumber, Length)`. +- `2) $NextNumber = Current(Code, Length).Id + 1`, then `$NextCode = ConvertTo_Code($NextNumber, Length)`. +- `Previous` returns `{Code:$PrevCode, Id:$PrevNumber}` and `Next` returns `{Code:$NextCode, Id:$NextNumber}` after conversion compatibility is applied. +- Boundary rule: if `Previous` is called on the first code, throw `ERR_SEQUENCE_START`; if `Next` is called on the last code, throw `ERR_SEQUENCE_END`. +- `Id(Number, Length)` output contract is defined by the canonical Id route rule and conversion rules above. +- `Current` mode: +- `Current -> ConvertTo_Id/ConvertTo_Code (core operations only)` +- Shared sequencing block (`Beginy`, `Previous`, `Next`, `End`): +- `Mode -> (Current -> (Sequence_OP -> ExistenceCheck))` +- `Exists` -> deterministic fallback walk (`Backward`/`Forward`) +- `Not Exists` -> return/commit +- `Random` mode: +- `Random_OP -> Current -> ExistenceCheck` +- `Exists` -> regenerate/retry +- `Not Exists` -> return/commit +- `Random` must not use deterministic fallback walk. +- `Id` mode: +- Core Id mode flow: see canonical Id route rule defined above (single source of truth). +- Generate by `Id:Number` mapping, then apply existence decision rules. +- For deterministic fallback walk: step = generate candidate -> `ExistenceCheck`. +- Stop on boundary/limit -> throw conflict error. +- Commit safety rule: after `Exists=false`, insert/commit with unique constraint (or lock) to avoid race conditions. +- Summary: `Random = regenerate`; deterministic modes = advance to next valid candidate, not same-input retry. +- Core uniqueness baseline: `Runtime` tracking is a dedicated first-stage source in `ExistenceCheck` flow. +- External uniqueness source strategy (`DB/Cache/Memory/Callback`) is supported through `ExistenceCheck(...)` source adapters after `Runtime` stage. +- Core retry safety defaults: `Random_Max_Retries = 1000` and `Max_Random_Time_Ms = 200`. +- Deterministic fallback safety defaults: `Deterministic_Max_Steps = 1000` and `Deterministic_Max_Time_Ms = 200`. +- If random uniqueness cannot complete within retry/time limits (or code space is exhausted), throw `ERR_RANDOM_SPACE_EXHAUSTED`. +- If deterministic fallback cannot complete within step/time limits (or boundary is reached with no available candidate), throw `ERR_SEQUENCE_CONFLICT`. +- Strict range rule for `Id`: define `MaxId = (N^Length) - 1`; if `Number > MaxId`, throw `ERR_ID_OUT_OF_RANGE` and do not auto-expand `Length`. +- All modes must support conversion compatibility between one another through `{Code, Id}`. + +## 8) Positioning Model (Code <-> Id) +Use base-N conversion: +- `N = Len(Compiled_Alphabet)` +- Leftmost char is most significant digit. +- Digit value = index of char in compiled alphabet. + +`ConvertTo_Id(Code, Length) -> Id`: +- Parse `Code` as base-N integer. +- Used by `Current`, `Previous`, and `Next` (and internal `Reverse` helper when needed). + +`ConvertTo_Code(Id, Length) -> Code`: +- Convert integer to base-N and left-pad with first alphabet character to required `Length`. +- Used by `Beginy`, `Previous`, `Next`, `End`, `Random`, and `Id` (and internal `Reverse` helper when needed). + +Example with profile where first char is `A`: +- `AAAAAAAA` -> `0` +- `AAAAAAAB` -> `1` +- `AAAAAAAC` -> `2` + +Important: +- These examples are valid only when compiled alphabet starts with `A` and `Length = 8`. + +## 9) Validation (On Hold) and Errors +Runtime error contract: +- Core behavior (CANG_Core): throw exceptions only for core operation errors (typed exception recommended, e.g., CANG_Exception) with stable error key. +- Boundary behavior (API/UI layer): catch core exceptions and return only important error data: `{Ok:false,Error,Description}`. +- `Description` must be short, human-readable, and safe (no internal stack traces or sensitive data). + +Validation (external file, on hold): +- `Profile_Id` must exist. +- Input `Code` must contain only characters from compiled alphabet. +- `Length` must be provided for generation/conversion modes. +- `Length` must be integer >= 1. +- For code-input modes, `strlen(Code)` must equal `Length`. +- If project policy minimum is enabled (example `8`), enforce that minimum. +- `Id` must be integer >= 0. +- For `Id(Number, Length)`, `Number` must satisfy `0 <= Number <= (N^Length)-1`; otherwise throw `ERR_ID_OUT_OF_RANGE`. + +Suggested error keys: +- `ERR_PROFILE_NOT_FOUND` +- `ERR_INVALID_ALPHABET` +- `ERR_INVALID_CODE_CHAR` +- `ERR_INVALID_CODE_LENGTH` +- `ERR_INVALID_ID` +- `ERR_ID_OUT_OF_RANGE` +- `ERR_MODE_INPUT_REQUIRED` +- `ERR_LENGTH_REQUIRED` +- `ERR_INVALID_LENGTH` +- `ERR_LENGTH_MISMATCH` +- `ERR_SEQUENCE_START` +- `ERR_SEQUENCE_END` +- `ERR_SEQUENCE_CONFLICT` +- `ERR_RANDOM_SPACE_EXHAUSTED` + +## 10) Determinism and Security +- Deterministic operations: `Beginy`, `Previous`, `Current`, `Next`, `End`, `Id`. +- Non-deterministic operation: `Random`. +- `Random` must use cryptographically secure source in PHP (for example `random_int`). + +## 11) Implementation Notes +- Keep one single source of truth for profiles (CANG_Config). +- CANG_Language should only resolve and normalize profile data. +- CANG_ProFile should only handle ordering/selection logic. +- CANG_Core should only perform generation/conversion operations. +- `ValidateCore(...)` is moved out of `CANG_Core` and is on hold for a separate validation file. +- CANG_Core must expose ExistenceCheck(Length, Code, Id): {Exists: bool, Status: string, Reason: string, Description: string} as active core method for uniqueness checks. + + + +## 12) Core ExistenceCheck Sources +- This section defines source strategies used by active core `ExistenceCheck(...)`. +- Core method: +- `ExistenceCheck(Length, Code, Id): {Exists: bool, Status: string, Reason: string, Description: string}` +- Source priority order: `Runtime -> DB -> Cache -> Memory -> Callback`. +- Environment mode roles: +- `Development -> System Developer` +- `Testing -> BenchMark Validator` +- `Production -> DashBoard Administrator` +- Environment behavior mapping: +- `Development`: enabled sources -> `Runtime -> DB`; `Cache/Memory/Callback` optional; `CHECK_ERROR` in optional sources may continue with warning. +- `Testing`: enabled sources -> `Runtime -> DB -> Memory`; `Cache/Callback` optional; `CHECK_ERROR` fails test run by default. +- `Production`: enabled sources -> `Runtime -> DB -> Cache -> Memory -> Callback`; `DB` required; `CHECK_ERROR` from `Runtime/DB` stops flow immediately. +- Policy rule: deterministic/random collision handling stays the same across environments; only source availability and failure strictness change. +- Retry/error contract: `Random` retries on `Exists=true`; deterministic modes use fallback walk on `Exists=true`; throw on `CHECK_ERROR` unless policy says otherwise. +- Mini flow snippet: +- Sequencing modes (`Beginy`, `Previous`, `Next`, `End`): `Current -> Sequence_OP -> ExistenceCheck -> Return/Fallback`. +- `Current`: see canonical current core-operation flow in Section `7` (validation on hold/external). +- `Random`: `Random_OP -> Current -> ExistenceCheck -> Return/Retry`. +- `Id`: see canonical Id route rule (single source of truth), then `Return/Decision`. + +Optional payload examples: +- Success (Exists=true): `{Exists:true,Status:"CHECK_SUCCESS",Reason:"VALID_INPUT",Description:"Code already exists."}` +- Success (Exists=false): `{Exists:false,Status:"CHECK_SUCCESS",Reason:"VALID_INPUT",Description:"Code is available."}` +- Failure: `{Exists:false,Status:"CHECK_ERROR",Reason:"SOURCE_FAILED",Description:"Database lookup failed."}` + +Flow map: +- `Status=CHECK_CONFIG + Reason=NOT_CONFIGURED -> FLOW_EXISTENCE_CHECK_INPUT_NOT_READY` +- `Status=CHECK_ERROR + Reason=INVALID_INPUT -> FLOW_EXISTENCE_CHECK_INPUT_FAILED` +- `Status=CHECK_SUCCESS + Reason=VALID_INPUT -> FLOW_EXISTENCE_CHECK_INPUT_PASSED` +- `Status=CHECK_ERROR + Reason=SOURCE_FAILED -> FLOW_EXISTENCE_CHECK_SOURCE_FAILED` diff --git a/v.0.5.FinallVersion/Base_CANG_CommandAI.md b/v.0.5.FinallVersion/Base_CANG_CommandAI.md index 5cc23f4..b74d9c6 100644 --- a/v.0.5.FinallVersion/Base_CANG_CommandAI.md +++ b/v.0.5.FinallVersion/Base_CANG_CommandAI.md @@ -1,140 +1,193 @@ -Create PHP Code: - -Name: CANG_LanguageCharFoundation - -Fundamental Config File: - -Set The Fundamental Language Characters: -LanguageChar : Upper -> range('A','Z') -LanguageChar : Lower -> range('a','z') -LanguageChar : Numeric -> range('0','9') -LanguageChar : ShortSpecial -> str_split('_-') -LanguageChar : FullSpecial -> str_split('#$%&+-@_') - -Create PHP Class: - -Name: CANG_LanguageCharClass - -Set The Basic Language Name: -LanguageName : Alphabet_Upper -LanguageName : Alphabet_Lower -LanguageName : Alphabet_Mix -LanguageName : Numeric -LanguageName : Alphabet_Upper_Num -LanguageName : Alphabet_Lower_Num -LanguageName : Alphabet_Mix_Num -LanguageName : Alphabet_Mix_Num_SpecialShort -LanguageName : Alphabet_Mix_Num_SpecialFull - -Set The Basic Language Type: -LanguageType : '[A-Z]' -LanguageType : '[a-z]' -LanguageType : '[A-Z,a-z]' -LanguageType : '[0-9]' -LanguageType : '[A-Z,0-9]' -LanguageType : '[a-z,0-9]' -LanguageType : '[A-Z,a-z,0-9]' -LanguageType : '[A-Z,a-z,0-9,-_]' -LanguageType : '[A-Z,a-z,0-9,-_]' - -Set The Basic Language Description: -LanguageDescription : 'Alphabetical -> Simple: Capital letters' -LanguageDescription : 'Alphabetical -> Simple: Small letters' -LanguageDescription : 'Alphabetical -> Mix: Capital and Small letters' -LanguageDescription : 'Numerical -> Simple' -LanguageDescription : 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)' -LanguageDescription : 'Alphabetical and Numerical -> Simple: Small letters' -LanguageDescription : 'Alphabetical and Numerical -> Mix: Capital and Small letters' -LanguageDescription : 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)' -LanguageDescription : 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' - -Set The Basic Language Range: -LanguageRange : LanguageChar[Upper] -LanguageRange : LanguageChar[Lower] -LanguageRange : LanguageChar[Upper], LanguageChar[Lower] -LanguageRange : LanguageChar[Numeric] -LanguageRange : LanguageChar[Upper], LanguageChar[Numeric] -LanguageRange : LanguageChar[Lower], LanguageChar[Numeric] -LanguageRange : LanguageChar[Upper], LanguageChar[Lower], LanguageChar[Numeric] -LanguageRange : LanguageChar[Upper], LanguageChar[Lower], LanguageChar[Numeric], LanguageChar[ShortSpecial] -LanguageRange : LanguageChar[Upper], LanguageChar[Lower], LanguageChar[Numeric], LanguageChar[FullSpecial] - -Set The Basic Language Id: -LanguageId : 1 -LanguageId : 2 -LanguageId : 3 -LanguageId : 4 -LanguageId : 5 -LanguageId : 6 -LanguageId : 7 -LanguageId : 8 -LanguageId : 9 - -Set The Basic Language Order: -LanguageOrder : LanguageId, LanguageName, LanguageType, LanguageDescription, LanguageRange - -Set The Basic Language Definition: -LanguageDefinition -> LanguageOrder - -Name: Complex Alpha Numeric Generator (CANG) - -Create PHP CANG Class: - -Able To Select Language: -LanguageDefinition + +--- +Project Name: Complex Alpha Numeric Generator (CANG) + +Project Description: 'The Complex Alpha Numeric Generator (CANG) is a PHP‑based utility designed to produce highly customizable alphanumeric strings for use in authentication systems, token creation, unique identifiers, and data‑randomization workflows. Built for developers who need both flexibility and reliability, CANG supports layered configuration options including character‑set selection, entropy tuning, pattern enforcement, and optional cryptographic strengthening. CANG’s architecture emphasizes modularity and clean integration. It can operate as a standalone function, a reusable class, or a plug‑in component within larger PHP applications. Its deterministic configuration model ensures repeatable behavior when needed, while still offering strong randomness for security‑sensitive contexts. Whether you’re generating session keys, invitation codes, randomized filenames, or structured alphanumeric sequences, CANG provides a robust, developer‑friendly foundation that adapts to a wide range of project requirements.' + +Project Type: PHP + +Project Schema: Universal + +Project Definition: + +The Fundamental Language Symbols: +Language_Symbol : Upper -> range('A','Z') +Language_Symbol : Lower -> range('a','z') +Language_Symbol : Numeric -> range('0','9') +Language_Symbol : CharShort -> str_split('_-') +Language_Symbol : CharLong -> str_split('#$%&+-@') + +The Basic Language Name: +Language_Name : Alphabet_Upper +Language_Name : Alphabet_Lower +Language_Name : Alphabet_Mix +Language_Name : Numeric +Language_Name : Alphabet_Upper_Num +Language_Name : Alphabet_Lower_Num +Language_Name : Alphabet_Mix_Num +Language_Name : Alphabet_Mix_Num_CharShort +Language_Name : Alphabet_Mix_Num_CharLong +Language_Name : Alphabet_Mix_Num_CharMix + +The Basic Language Type: +Language_Type : '[A-Z]' +Language_Type : '[a-z]' +Language_Type : '[A-Z]', '[a-z]' +Language_Type : '[0-9]' +Language_Type : '[A-Z]', '[0-9]' +Language_Type : '[a-z]', '[0-9]' +Language_Type : '[A-Z]', '[a-z]', '[0-9]' +Language_Type : '[A-Z]', '[a-z]', '[0-9]', '[-_]' +Language_Type : '[A-Z]', '[a-z]', '[0-9]', '[#$%+-@]' +Language_Type : '[A-Z]', '[a-z]', '[0-9]', '[-_]', '[#$%+-@]' + +The Basic Language Description: +Language_Description : 'Alphabetical -> Simple: Capital Letters' +Language_Description : 'Alphabetical -> Simple: Small Letters' +Language_Description : 'Alphabetical -> Mix: Capital And Small Letters' +Language_Description : 'Numerical -> Simple' +Language_Description : 'Alphabetical And Numerical -> Simple: Capital Letters (Megaupload.com)' +Language_Description : 'Alphabetical And Numerical -> Simple: Small Letters' +Language_Description : 'Alphabetical And Numerical -> Mix: Capital And Small Letters' +Language_Description : 'Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Short Special Chars (YouTube.com)' +Language_Description : 'Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Long Special Chars (Safe Password)' +Language_Description : 'Alphabetical And Numerical -> Mix: Capital/Small Letters Plus Full Special Chars (Safe Password)' + +The Basic Language Range: +Language_Range : Language_Symbol[Upper] +Language_Range : Language_Symbol[Lower] +Language_Range : Language_Symbol[Upper], Language_Symbol[Lower] +Language_Range : Language_Symbol[Numeric] +Language_Range : Language_Symbol[Upper], Language_Symbol[Numeric] +Language_Range : Language_Symbol[Lower], Language_Symbol[Numeric] +Language_Range : Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric] +Language_Range : Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric], Language_Symbol[CharShort] +Language_Range : Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric], Language_Symbol[CharLong] +Language_Range : Language_Symbol[Upper], Language_Symbol[Lower], Language_Symbol[Numeric], Language_Symbol[CharShort], Language_Symbol[CharLong] + +The Basic Language Id: +Language_Id : 0 +Language_Id : 1 +Language_Id : 2 +Language_Id : 3 +Language_Id : 4 +Language_Id : 5 +Language_Id : 6 +Language_Id : 7 +Language_Id : 8 +Language_Id : 9 + +--- +ToDo List: +Config, +Language, +ProFile, +CANG + +--- +The Design Of The Files: Config, Language, ProFile, CANG + +File Name: CANG_Config +File Description: It Is A Complex Array With Architecture Of Fundamental Configuration That Is Loaded InTo Language Class. + +File Name: CANG_Language +File Description: It Is A Complex Language Class That Load The Config Of The Language InTo Sortable Order That Is Loaded InTo ProFile. + +Set The Basic Language_Order(Language_Id, Language_Name, Language_Type, Language_Description) -> Language_Range + +File Name: CANG_ProFile +File Description:It Is A Complex Language ProFile Class That Load The Language Class InTo SelectAble Order That Is Loaded InTo CANG Core. + +The ProFile Must Be Able To Select The Symbol, Type, Range Of The Language And Order Them Accoding To Selection. +The Selection Of Language Is Based On Language_Id To Set Default_Language. +The Selection Of Language_Range Must Be Able To Language Rotate As Developer/User Decide To Sort By Canonical Order Language_Range, Language_Type +Example: + +Language_Range() -> If More Than One The Order Does Work + +Default_Language -> Language_Id +Default_Order -> Language_Range(Upper, Lower, Numeric, CharShort, CharLong) + +Default_Language -> Language_Id +Default_Order -> Language_Range(CharLong, CharShort, Numeric, Lower, Upper) + + +File Name: CANG_Core +File Description: It Is A Complex CANG Class That Load The ProFile Class InTo The Fields To Select Mode And Lenght Of The Generated Code For Next Developer/User Process. Able To Change Length: Minimum Length = 8 Able To Select Generation Mode: -GenerateMode : Beginning, Current, Next, Previous, End, Random, Id +GenerateMode : Beginning, Previous, Current, Next, End, Random, Id Example Mode Selection: -Mode : Beginning(:NoInPut:) -Mode : Current(:InPutString:) -Mode : Next(:InPutString:) -Mode : Previous(:InPutString:) -Mode : End(:NoInPut:) -Mode : Random(:NoInPut:) -Mode : Id(:InPutNumber:) - -Able To Read Position: +Mode : Beginning(:NoInPut:) -> Id(:InPutNumber:) +Mode : Previous(:InPutString:) -> Id(:InPutNumber:) +Mode : Current(:InPutString:) -> Id(:InPutNumber:) +Mode : Next(:InPutString:) -> Id(:InPutNumber:) +Mode : End(:NoInPut:) -> Id(:InPutNumber:) +Mode : Random(:NoInPut:) -> Id(:InPutNumber:) +Mode : Id(:InPutNumber:) -> Current(:InPutString:) + +Able To Read Position: Id(:InPutNumber:) Example: -AAAAAAAA = 0 -AAAAAAAB = 1 -AAAAAAAC = 2 - -ReadMe: -Write Nice Referencial ReadMe MarkDown With Logic And Development For GitHub About The CANG That Includes Language Char Followed By Language Definition And Language Selector To Gain Settings For CANG And Generate OutPut String That Is Compatible According To -Language Name: -1 => 'Alphabet_Upper', -2 => 'Alphabet_Lower', -3 => 'Alphabet_Mix', -4 => 'Numeric', -5 => 'Alphabet_Upper_Num', -6 => 'Alphabet_Lower_Num', -7 => 'Alphabet_Mix_Num', -8 => 'Alphabet_Mix_Num_SpecialShort', -9 => 'Alphabet_Mix_Num_SpecialFull' - -Language Type: -1 => '[A-Z]', -2 => '[a-z]', -3 => '[A-Z,a-z]', -4 => '[0-9]', -5 => '[A-Z,0-9]', -6 => '[a-z,0-9]', -7 => '[A-Z,a-z,0-9]', -8 => '[A-Z,a-z,0-9,-_]', -9 => '[A-Z,a-z,0-9,-_]' - -Language Description: -1 => 'Alphabetical -> Simple: Capital letters', -2 => 'Alphabetical -> Simple: Small letters', -3 => 'Alphabetical -> Mix: Capital and Small letters', -4 => 'Numerical -> Simple', -5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', -6 => 'Alphabetical and Numerical -> Simple: Small letters', -7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', -8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', -9 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' + 'Code Generation' / 'Program Friendly' / 'Developer/User Friendly' +AAAAAAAA = 0 -> 1 +AAAAAAAB = 1 -> 2 +AAAAAAAC = 2 -> 3 + + +Code Array: Old Schema + public function CodeArray(){ + $code_base = implode($this->code_char_base); + if($this->default_code_length==strlen($code_base)){ + return array( + 'code_base'=>$code_base, + 'code_base_md5'=>md5($code_base), + 'code_base_sha1'=>sha1($code_base), + 'code_base64_encode'=>base64_encode($code_base), + 'code_max_number'=>$this->CodeType['code_max_number'], + 'code_pos_num'=>$this->code_pos_num, + 'code_time'=>$this->CodeType['code_generated_time'], + 'code_message'=>'is_acurrate', + 'code_name'=>$this->CodeType['code_name'], + 'code_description'=>$this->CodeType['code_description'], + 'code_type'=>$this->default_code_type, + 'code_max_type'=>$this->code_max_type, + 'code_length'=>$this->default_code_length + ); + }elseif($this->default_code_length$code_base, + 'code_base_md5'=>md5($code_base), + 'code_base_sha1'=>sha1($code_base), + 'code_base64_encode'=>base64_encode($code_base), + 'code_max_number'=>$this->CodeType['code_max_number'], + 'code_pos_num'=>$this->code_pos_num, + 'code_time'=>$this->CodeType['code_generated_time'], + 'code_message'=>'is_upper_or_full', + 'code_name'=>$this->CodeType['code_name'], + 'code_description'=>$this->CodeType['code_description'], + 'code_type'=>$this->default_code_type, + 'code_max_type'=>$this->code_max_type, + 'code_length'=>$this->default_code_length + ); + }else{ + return array( + 'code_base'=>$code_base, + 'code_base_md5'=>md5($code_base), + 'code_base_sha1'=>sha1($code_base), + 'code_base64_encode'=>base64_encode($code_base), + 'code_max_number'=>$this->CodeType['code_max_number'], + 'code_pos_num'=>$this->code_pos_num, + 'code_time'=>$this->CodeType['code_generated_time'], + 'code_message'=>'is_lower', + 'code_name'=>$this->CodeType['code_name'], + 'code_description'=>$this->CodeType['code_description'], + 'code_type'=>$this->default_code_type, + 'code_max_type'=>$this->code_max_type, + 'code_length'=>$this->default_code_length + ); + } + } \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php b/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php deleted file mode 100644 index 8432bce..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Config/CANG_LanguageChar.php +++ /dev/null @@ -1,32 +0,0 @@ - [ - - // A–Z - 'Upper' => range('A', 'Z'), - - // a–z - 'Lower' => range('a', 'z'), - - // 0–9 - 'Numeric' => range('0', '9'), - - // Minimal special characters - 'ShortSpecial' => str_split('_-'), - - // Full special character set - 'FullSpecial' => str_split('#$%&+-@_'), - ], - -]; -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Display.php b/v.0.5.FinallVersion/Base_CANG_Display.php deleted file mode 100644 index 7d0d2c1..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Display.php +++ /dev/null @@ -1,44 +0,0 @@ -byId(7); -// Or Select By Name -$CANG_LanguageRange = $CANG_LanguageSelect->byName('Alphabet_Mix_Num'); -// OutPut Selection -print_r($Select->output($CANG_LanguageRange)); - -// Insert This To Run CANG: -$CANG = New CANG($CANG_LanguageRange, 8); - -echo $CANG->generate(CANG::MODE_BEGINNING); // AAAAAAAA -echo $CANG->generate(CANG::MODE_ID, "0"); // AAAAAAAA -echo $CANG->generate(CANG::MODE_ID, "1"); // AAAAAAAB -echo $CANG->generate(CANG::MODE_ID, "2"); // AAAAAAAC -echo $CANG->generate(CANG::MODE_NEXT, "AAAAAAAB"); // AAAAAAAC -echo $CANG->stringToPosition("AAAAAAAC"); // 2 -*/ diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG.php b/v.0.5.FinallVersion/Base_CANG_Generators/CANG.php deleted file mode 100644 index 376f5c4..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Generators/CANG.php +++ /dev/null @@ -1,175 +0,0 @@ -setLanguage($languageDefinition); - $this->setLength($length); - } - - // --------------------------------------------------------- - // LANGUAGE + LENGTH - // --------------------------------------------------------- - - public function setLanguage(array $languageDefinition): void - { - if (empty($languageDefinition)) { - throw new InvalidArgumentException("Language definition cannot be empty."); - } - - $this->language = array_values($languageDefinition); - } - - public function setLength(int $length): void - { - if ($length < 8) { - throw new InvalidArgumentException("Minimum length is 8."); - } - $this->length = $length; - } - - // --------------------------------------------------------- - // CORE: POSITION → STRING - // --------------------------------------------------------- - - public function positionToString(int $position): string - { - if ($position < 0) { - throw new InvalidArgumentException("Position cannot be negative."); - } - - $base = count($this->language); - $result = ''; - - while ($position >= 0) { - $result = $this->language[$position % $base] . $result; - $position = intdiv($position, $base) - 1; - } - - return str_pad($result, $this->length, $this->language[0], STR_PAD_LEFT); - } - - // --------------------------------------------------------- - // CORE: STRING → POSITION - // --------------------------------------------------------- - - public function stringToPosition(string $string): int - { - if (strlen($string) !== $this->length) { - throw new InvalidArgumentException("Input string must be exactly {$this->length} characters."); - } - - $base = count($this->language); - $chars = str_split($string); - $position = 0; - - foreach ($chars as $char) { - $index = array_search($char, $this->language, true); - if ($index === false) { - throw new InvalidArgumentException("Invalid character '$char' in input."); - } - $position = $position * $base + ($index + 1); - } - - return $position - 1; - } - - // --------------------------------------------------------- - // GENERATION MODES - // --------------------------------------------------------- - - public function generate(string $mode, ?string $current = null): string - { - switch ($mode) { - - case self::MODE_BEGINNING: - return str_repeat($this->language[0], $this->length); - - case self::MODE_END: - return str_repeat(end($this->language), $this->length); - - case self::MODE_RANDOM: - return $this->randomString(); - - case self::MODE_CURRENT: - if ($current === null) { - throw new InvalidArgumentException("Current mode requires input string."); - } - return $current; - - case self::MODE_NEXT: - if ($current === null) { - throw new InvalidArgumentException("Next mode requires input string."); - } - return $this->positionToString($this->stringToPosition($current) + 1); - - case self::MODE_PREVIOUS: - if ($current === null) { - throw new InvalidArgumentException("Previous mode requires input string."); - } - return $this->positionToString( - max(0, $this->stringToPosition($current) - 1) - ); - - case self::MODE_ID: - if ($current === null || !ctype_digit((string)$current)) { - throw new InvalidArgumentException("Id mode requires a numeric input."); - } - return $this->positionToString((int)$current); - - default: - throw new InvalidArgumentException("Unknown mode '$mode'."); - } - } - - // --------------------------------------------------------- - // RANDOM GENERATOR - // --------------------------------------------------------- - - protected function randomString(): string - { - $result = ''; - $max = count($this->language) - 1; - - for ($i = 0; $i < $this->length; $i++) { - $result .= $this->language[random_int(0, $max)]; - } - - return $result; - } -} -/* -Example: How To Use - -$language = range('A', 'Z'); -$CANG = New CANG($language, 8); - -echo $CANG->generate(CANG::MODE_BEGINNING); // AAAAAAAA -echo $CANG->generate(CANG::MODE_ID, "0"); // AAAAAAAA -echo $CANG->generate(CANG::MODE_ID, "1"); // AAAAAAAB -echo $CANG->generate(CANG::MODE_ID, "2"); // AAAAAAAC - -echo $CANG->generate(CANG::MODE_NEXT, "AAAAAAAB"); // AAAAAAAC -echo $CANG->stringToPosition("AAAAAAAC"); // 2 -*/ -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php b/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php deleted file mode 100644 index 7278ef1..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Benchmark.php +++ /dev/null @@ -1,85 +0,0 @@ -cang = new CANG(range('A', 'Z'), 8); - } - - public function run(int $startId, int $endId, bool $warmup = true): void - { - echo "=== CANG BENCHMARK ===\n"; - echo "Range: $startId → $endId\n"; - echo "Total IDs: " . ($endId - $startId + 1) . "\n\n"; - - if ($warmup) { - $this->warmup(); - } - - $this->benchmark($startId, $endId); - } - - // --------------------------------------------------------- - // WARMUP (optional) - // --------------------------------------------------------- - - protected function warmup(): void - { - echo "--- Warmup Pass (stabilizing CPU cache) ---\n"; - - $this->cang->generate(CANG::MODE_ID, "0"); - $this->cang->generate(CANG::MODE_ID, "1000"); - $this->cang->generate(CANG::MODE_ID, "500000"); - - echo "Warmup complete.\n\n"; - } - - // --------------------------------------------------------- - // MAIN BENCHMARK - // --------------------------------------------------------- - - protected function benchmark(int $startId, int $endId): void - { - echo "--- Running Benchmark ---\n"; - - $count = $endId - $startId + 1; - - $startTime = microtime(true); - $startMemory = memory_get_usage(true); - - for ($i = $startId; $i <= $endId; $i++) { - $this->cang->generate(CANG::MODE_ID, (string)$i); - } - - $endTime = microtime(true); - $endMemory = memory_get_usage(true); - - $duration = $endTime - $startTime; - $memoryUsed = $endMemory - $startMemory; - $avgPerId = $duration / $count; - $idsPerSecond = $count / $duration; - - echo "Duration: " . number_format($duration, 6) . " sec\n"; - echo "Avg per ID: " . number_format($avgPerId, 9) . " sec\n"; - echo "IDs per second: " . number_format($idsPerSecond, 2) . "\n"; - echo "Memory used: " . number_format($memoryUsed / 1024, 2) . " KB\n"; - - echo "\n--- Benchmark Complete ---\n"; - } -} - -/* -Example: How To Benchmark - -require "CANG.php"; -require "CANG_Benchmark.php"; - -$bench = New CANG_Benchmark(); - -// Example: benchmark 0 → 1,000,000 -$bench->run(0, 1000000); -*/ -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php b/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php deleted file mode 100644 index ad75c44..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Generators/CANG_Test.php +++ /dev/null @@ -1,119 +0,0 @@ -cang = new CANG(range('A', 'Z'), 8); - } - - public function run(): void - { - echo "=== CANG TEST SUITE ===\n\n"; - - $this->testBeginning(); - $this->testEnd(); - $this->testRandom(); - $this->testIdMode(); - $this->testNextPrevious(); - $this->testStringPositionMapping(); - - echo "\n=== TESTING COMPLETE ===\n"; - } - - protected function assertEqual($expected, $actual, string $label): void - { - $status = ($expected === $actual) ? "PASS" : "FAIL"; - echo sprintf( - "%-30s : %-5s | Expected: %-12s Got: %-12s\n", - $label, - $status, - $expected, - $actual - ); - } - - // --------------------------------------------------------- - // INDIVIDUAL TESTS - // --------------------------------------------------------- - - protected function testBeginning(): void - { - echo "--- Beginning Mode ---\n"; - $result = $this->cang->generate(CANG::MODE_BEGINNING); - $this->assertEqual("AAAAAAAA", $result, "Beginning"); - echo "\n"; - } - - protected function testEnd(): void - { - echo "--- End Mode ---\n"; - $result = $this->cang->generate(CANG::MODE_END); - $this->assertEqual("ZZZZZZZZ", $result, "End"); - echo "\n"; - } - - protected function testRandom(): void - { - echo "--- Random Mode ---\n"; - $result = $this->cang->generate(CANG::MODE_RANDOM); - echo "Random Output: $result\n\n"; - } - - protected function testIdMode(): void - { - echo "--- ID Mode ---\n"; - $this->assertEqual("AAAAAAAA", $this->cang->generate(CANG::MODE_ID, "0"), "ID 0"); - $this->assertEqual("AAAAAAAB", $this->cang->generate(CANG::MODE_ID, "1"), "ID 1"); - $this->assertEqual("AAAAAAAC", $this->cang->generate(CANG::MODE_ID, "2"), "ID 2"); - echo "\n"; - } - - protected function testNextPrevious(): void - { - echo "--- Next / Previous ---\n"; - - $this->assertEqual( - "AAAAAAAC", - $this->cang->generate(CANG::MODE_NEXT, "AAAAAAAB"), - "Next" - ); - - $this->assertEqual( - "AAAAAAAB", - $this->cang->generate(CANG::MODE_PREVIOUS, "AAAAAAAC"), - "Previous" - ); - - echo "\n"; - } - - protected function testStringPositionMapping(): void - { - echo "--- String <-> Position ---\n"; - - $this->assertEqual(0, $this->cang->stringToPosition("AAAAAAAA"), "Pos AAAAAAAA"); - $this->assertEqual(1, $this->cang->stringToPosition("AAAAAAAB"), "Pos AAAAAAAB"); - $this->assertEqual(2, $this->cang->stringToPosition("AAAAAAAC"), "Pos AAAAAAAC"); - - $this->assertEqual("AAAAAAAA", $this->cang->positionToString(0), "Str 0"); - $this->assertEqual("AAAAAAAB", $this->cang->positionToString(1), "Str 1"); - $this->assertEqual("AAAAAAAC", $this->cang->positionToString(2), "Str 2"); - - echo "\n"; - } -} - -/* -Example: How To Test - -require "CANG.php"; -require "CANG_Test.php"; - -$CANGTest = New CANG_Test(); -$CANGTest->run(); - -*/ -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php deleted file mode 100644 index 23a024c..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCharClass.php +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php deleted file mode 100644 index 54d5146..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageCode.php +++ /dev/null @@ -1,88 +0,0 @@ - range('A', 'Z'), - 'Lower' => range('a', 'z'), - 'Numeric' => range('0', '9'), - 'ShortSpecial' => str_split('_-'), - 'FullSpecial' => str_split('#$%&+-@_') -]; - -/** - * Basic Language Names - */ -$LanguageName = [ - 1 => 'Alphabet_Upper', - 2 => 'Alphabet_Lower', - 3 => 'Alphabet_Mix', - 4 => 'Numeric', - 5 => 'Alphabet_Upper_Num', - 6 => 'Alphabet_Lower_Num', - 7 => 'Alphabet_Mix_Num', - 8 => 'Alphabet_Mix_Num_SpecialShort', - 9 => 'Alphabet_Mix_Num_SpecialFull' -]; - -/** - * Basic Language Types - */ -$LanguageType = [ - 1 => '[A-Z]', - 2 => '[a-z]', - 3 => '[A-Z,a-z]', - 4 => '[0-9]', - 5 => '[A-Z,0-9]', - 6 => '[a-z,0-9]', - 7 => '[A-Z,a-z,0-9]', - 8 => '[A-Z,a-z,0-9,-_]', - 9 => '[A-Z,a-z,0-9,-_]' -]; - -/** - * Basic Language Descriptions - */ -$LanguageDescription = [ - 1 => 'Alphabetical -> Simple: Capital letters', - 2 => 'Alphabetical -> Simple: Small letters', - 3 => 'Alphabetical -> Mix: Capital and Small letters', - 4 => 'Numerical -> Simple', - 5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', - 6 => 'Alphabetical and Numerical -> Simple: Small letters', - 7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', - 8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', - 9 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' -]; - -/** - * Basic Language Ranges - */ -$LanguageRange = [ - 1 => [$LanguageChar['Upper']], - 2 => [$LanguageChar['Lower']], - 3 => [$LanguageChar['Upper'], $LanguageChar['Lower']], - 4 => [$LanguageChar['Numeric']], - 5 => [$LanguageChar['Upper'], $LanguageChar['Numeric']], - 6 => [$LanguageChar['Lower'], $LanguageChar['Numeric']], - 7 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric']], - 8 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['ShortSpecial']], - 9 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['FullSpecial']] -]; - -/** - * Language Definition (Ordered) - */ -$LanguageDefinition = []; - -foreach (range(1, 9) as $id) { - $LanguageDefinition[$id] = [ - 'LanguageId' => $id, - 'LanguageName' => $LanguageName[$id], - 'LanguageType' => $LanguageType[$id], - 'LanguageDescription' => $LanguageDescription[$id], - 'LanguageRange' => $LanguageRange[$id], - ]; -} -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php deleted file mode 100644 index d27531d..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageProfile.php +++ /dev/null @@ -1,138 +0,0 @@ -id = $id; - $this->name = $name; - $this->type = $type; - $this->description = $description; - $this->range = $range; - } - - // ----------------------------- - // Accessors - // ----------------------------- - - public function getId(): int - { - return $this->id; - } - - public function getName(): string - { - return $this->name; - } - - public function getType(): string - { - return $this->type; - } - - public function getDescription(): string - { - return $this->description; - } - - public function getRange(): array - { - return $this->range; - } - - // ----------------------------- - // Utility - // ----------------------------- - - public function getFlattenedRange(): array - { - return array_merge(...$this->range); - } - - public function containsChar(string $char): bool - { - return in_array($char, $this->getFlattenedRange(), true); - } - - // ----------------------------- - // Factory: Build All Definitions: Edit The Profile To Add Language Definition - // Start With Number 1 To Avoid Conflict With Null,False - // ----------------------------- - - public static function BuildAll(array $LanguageChar): array - { - $LanguageName = [ - 1 => 'Alphabet_Upper', - 2 => 'Alphabet_Lower', - 3 => 'Alphabet_Mix', - 4 => 'Numeric', - 5 => 'Alphabet_Upper_Num', - 6 => 'Alphabet_Lower_Num', - 7 => 'Alphabet_Mix_Num', - 8 => 'Alphabet_Mix_Num_SpecialShort', - 9 => 'Alphabet_Mix_Num_SpecialFull' - ]; - - $LanguageType = [ - 1 => '[A-Z]', - 2 => '[a-z]', - 3 => '[A-Z,a-z]', - 4 => '[0-9]', - 5 => '[A-Z,0-9]', - 6 => '[a-z,0-9]', - 7 => '[A-Z,a-z,0-9]', - 8 => '[A-Z,a-z,0-9,-_]', - 9 => '[A-Z,a-z,0-9,-_]' - ]; - - $LanguageDescription = [ - 1 => 'Alphabetical -> Simple: Capital letters', - 2 => 'Alphabetical -> Simple: Small letters', - 3 => 'Alphabetical -> Mix: Capital and Small letters', - 4 => 'Numerical -> Simple', - 5 => 'Alphabetical And Numerical -> Simple: Capital letters (Megaupload.com)', - 6 => 'Alphabetical and Numerical -> Simple: Small letters', - 7 => 'Alphabetical and Numerical -> Mix: Capital and Small letters', - 8 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Short Special chars (YouTube.com)', - 9 => 'Alphabetical and Numerical -> Mix: Capital/Small letters plus Full Special chars (Safe Password)' - ]; - - $LanguageRange = [ - 1 => [$LanguageChar['Upper']], - 2 => [$LanguageChar['Lower']], - 3 => [$LanguageChar['Upper'], $LanguageChar['Lower']], - 4 => [$LanguageChar['Numeric']], - 5 => [$LanguageChar['Upper'], $LanguageChar['Numeric']], - 6 => [$LanguageChar['Lower'], $LanguageChar['Numeric']], - 7 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric']], - 8 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['ShortSpecial']], - 9 => [$LanguageChar['Upper'], $LanguageChar['Lower'], $LanguageChar['Numeric'], $LanguageChar['FullSpecial']] - ]; - - $definitions = []; - - foreach (range(1, 9) As $id) { - $definitions[$id] = New Self( - $id, - $LanguageName[$id], - $LanguageType[$id], - $LanguageDescription[$id], - $LanguageRange[$id] - ); - } - - return $definitions; - } -} -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php b/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php deleted file mode 100644 index 193a000..0000000 --- a/v.0.5.FinallVersion/Base_CANG_Language/CANG_LanguageSelect.php +++ /dev/null @@ -1,49 +0,0 @@ -definitions = $definitions; - } - - // --------------------------------------------------------- - // Selectors - // --------------------------------------------------------- - - public function byId(int $id): ?CANG_LanguageProfile - { - return $this->definitions[$id] ?? null; - } - - public function byName(string $name): ?CANG_LanguageProfile - { - foreach ($this->definitions as $definition) { - if ($definition->getName() === $name) { - return $definition; - } - } - return null; - } - - // --------------------------------------------------------- - // Output Formatter - // --------------------------------------------------------- - - public function output(CANG_LanguageProfile $definition): array - { - return [ - 'id' => $definition->getId(), - 'name' => $definition->getName(), - 'type' => $definition->getType(), - 'description' => $definition->getDescription(), - 'range' => $definition->getRange(), - 'flattened' => $definition->getFlattenedRange(), - ]; - } -} -?> \ No newline at end of file diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID.php deleted file mode 100644 index bc08463..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID.php +++ /dev/null @@ -1,8 +0,0 @@ -SetLength(8); -$CANG->SetType(5); -$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID -print_r($return); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php deleted file mode 100644 index 7f7170c..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_ID_JSON.php +++ /dev/null @@ -1,9 +0,0 @@ -SetLength(8); -$CANG->SetType(5); -$return = $CANG->Generate_ID(249996);//In 30 seconds you should be able to generate the key by this ID -header("Content-type:application/json"); -echo json_encode($return,true); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random.php deleted file mode 100644 index d9185db..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random.php +++ /dev/null @@ -1,8 +0,0 @@ -SetLength(8); -$CANG->SetType(5); -$return = $CANG->Generate_String(); -print_r($return); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php deleted file mode 100644 index ba850c8..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_Random_JSON.php +++ /dev/null @@ -1,9 +0,0 @@ -SetLength(8); -$CANG->SetType(5); -$return = $CANG->Generate_String(); -header("Content-type:application/json"); -echo json_encode($return,true); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String.php deleted file mode 100644 index a843dd4..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String.php +++ /dev/null @@ -1,11 +0,0 @@ -SetLength(8); -$CANG->SetType(5); -$CANG->CodeInput(); -$return[1] = $CANG->Generate_String(); -$CANG->CodeInput($return[1]['code_base']); -$return[] = $CANG->Generate_String(); -print_r($return); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String_JSON.php deleted file mode 100644 index 8050c54..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Generate_String_JSON.php +++ /dev/null @@ -1,12 +0,0 @@ -SetLength(8); -$CANG->SetType(5); -$CANG->CodeInput(); -$return[1] = $CANG->Generate_String(); -$CANG->CodeInput($return[1]['code_base']); -$return[] = $CANG->Generate_String(); -header("Content-type:application/json"); -echo json_encode($return,true); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php deleted file mode 100644 index 02f3262..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID.php +++ /dev/null @@ -1,6 +0,0 @@ -byID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID -print_r($return); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php deleted file mode 100644 index 55a9877..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_ID_JSON.php +++ /dev/null @@ -1,7 +0,0 @@ -byID(249996000001111333338888555578963201457);//In 30 seconds you should be able to generate the key by this ID -header("Content-type:application/json"); -echo json_encode($return,true); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php deleted file mode 100644 index e38b1f0..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random.php +++ /dev/null @@ -1,6 +0,0 @@ -byRAND();//In 30 seconds you should be able to generate the key by this ID -print_r($return); -?> diff --git a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php b/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php deleted file mode 100644 index d41c3a5..0000000 --- a/v.0.5.FinallVersion/Base_CANG_NoMySQL_Examples/Example_Microsoft_SN_Generate_Random_JSON.php +++ /dev/null @@ -1,7 +0,0 @@ -byRAND();//In 30 seconds you should be able to generate the key by this ID -header("Content-type:application/json"); -echo json_encode($return,true) -?> From f051e86c08ad77aa0da849add9fe15bb9544bf27 Mon Sep 17 00:00:00 2001 From: Patrick ImProVision Date: Wed, 18 Feb 2026 14:52:34 +0100 Subject: [PATCH 72/72] Add Support Of Validation In CANG_DataBase --- .../Base_CANG/CANG_Driver/CANG_DataBase.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php index d9d3f3d..ac6c6c7 100644 --- a/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php +++ b/v.0.5.FinallVersion/Base_CANG/CANG_Driver/CANG_DataBase.php @@ -137,6 +137,49 @@ public function Delete(string $Table, array $Where): int return $Statement->rowCount(); } + /** + * Validate database existence check input/source and return check contract. + * + * Contract: + * - Status: CHECK_ERROR | CHECK_SUCCESS + * - Reason: INVALID_INPUT | VALID_INPUT | SOURCE_FAILED + * - Flow: FLOW_EXISTENCE_CHECK_INPUT_FAILED | FLOW_EXISTENCE_CHECK_INPUT_PASSED | FLOW_EXISTENCE_CHECK_SOURCE_FAILED + * + * @param array $Where + * @return array + */ + public function ExistenceCheck(string $Table, array $Where): array + { + if (trim($Table) === '' || $Where === []) { + return [ + 'Status' => 'CHECK_ERROR', + 'Reason' => 'INVALID_INPUT', + 'Flow' => 'FLOW_EXISTENCE_CHECK_INPUT_FAILED', + 'Exists' => false, + ]; + } + + try { + $Rows = $this->Select($Table, $Where, '*', 1); + $Exists = count($Rows) > 0; + + return [ + 'Status' => 'CHECK_SUCCESS', + 'Reason' => 'VALID_INPUT', + 'Flow' => 'FLOW_EXISTENCE_CHECK_INPUT_PASSED', + 'Exists' => $Exists, + ]; + } catch (\Throwable $Throwable) { + return [ + 'Status' => 'CHECK_ERROR', + 'Reason' => 'SOURCE_FAILED', + 'Flow' => 'FLOW_EXISTENCE_CHECK_SOURCE_FAILED', + 'Exists' => false, + 'Error_Message' => $Throwable->getMessage(), + ]; + } + } + /** * @param array $Where * @return array{0:string,1:array} @@ -184,4 +227,7 @@ private function BuildWhere(array $Where): array // 6) Delete $Removed = $DB->Delete('cang_codes', ['id' => $New_Id]); + +// 7) Existence check contract (for CANG_Driver generated code verification) +$Check = $DB->ExistenceCheck('cang_codes', ['code' => 'AB12CD34']); */