/** * 指定のプロパティにユニークコードをセットする * @param string $prop_name * @param integer $size * @return string 生成されたユニークコード */ public final function set_unique_code($prop_name, $size = null) { $code = ''; $max = !empty($size) ? $size : $this->prop_anon($prop_name, 'max', 32); $ctype = $this->prop_anon($prop_name, 'ctype', 'alnum'); if ($ctype != 'alnum' && $ctype != 'alpha' && $ctype != 'digit') { throw new \LogicException('unexpected ctype'); } $char = ''; if ($ctype == 'alnum' || $ctype == 'digit') { $char .= '0123456789'; } if ($ctype != 'digit') { if ($this->prop_anon($prop_name, 'upper', false) === true) { $char .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; } if ($this->prop_anon($prop_name, 'lower', true) === true) { $char .= 'abcdefghijklmnopqrstuvwxyz'; } } $ignores = $this->prop_anon($prop_name, 'ignore_auto_code'); $ignores = is_array($ignores) ? $ignores : array($ignores); $code = ''; $challenge = 0; $challenge_max = \org\rhaco\Conf::get('generate_code_challenge', 100); $bool = true; while ($code == '') { for ($i = 0; $i <= $challenge_max; $i++) { $code = \org\rhaco\lang\Code::rand($char, $max); $this->{$prop_name}($code); $bool = true; if ($this->{'verify_' . $prop_name}() === false) { $bool = false; } else { foreach ($ignores as $ignore) { if (preg_match('/^' . $ignore . '$/', $code)) { $bool = false; break; } } } if ($bool) { break; } } if ($bool && static::find_count(Q::eq($prop_name, $code)) == 0) { break; } if ($challenge++ > $challenge_max) { throw new \org\rhaco\store\db\exception\GenerateUniqueCodeRetryLimitOverException($prop_name . ': generate unique code retry limit over'); } $code = ''; $this->{$prop_name}($code); usleep(\org\rhaco\Conf::get('generate_code_retry_wait', 10000)); // 10ms } return $code; }
<?php $codebase = '0123456789ABC'; $max = \org\rhaco\lang\Code::max($codebase, 5); $maxcode = \org\rhaco\lang\Code::encode($codebase, $max); eq('CCCCC', $maxcode); eq($max, \org\rhaco\lang\Code::decode($codebase, $maxcode)); $min = \org\rhaco\lang\Code::min($codebase, 5); $mincode = \org\rhaco\lang\Code::encode($codebase, $min); eq('10000', $mincode); eq($min, \org\rhaco\lang\Code::decode($codebase, $mincode)); eq(3, strlen(\org\rhaco\lang\Code::rand($codebase, 3)));