Zend Framework生成独特的字符串

发布于 2024-12-05 06:39:21 字数 220 浏览 0 评论 0原文

我想生成一个唯一的4-6个char长字母数字字符串,以保存每个记录(用户)中的DB。 DB字段具有唯一的索引,因此尝试保存预先存在的字符串会生成错误。现在,我正在生成一个随机字符串并使用try-catch,因此在添加新记录时,如果引发异常,我会生成另一个随机字符串并尝试再次保存,并且代码继续尝试,直到成功添加记录为止。整个解决方案不仅看起来很重,而且很丑陋,所以我想更改它。我对优雅的解决方案感兴趣,因此欢迎任何帮助/指导。

I want to generate a unique 4-6 char long AlphaNumeric string to save in db with each record(user). The db field has a unique index, so trying to save a pre-existing string generates an error. Right now I am generating a random string and using try-catch, so when adding a new record if it throws an exception, I generate another random string and attempt to save again, and the code keep trying until it adds a record successfully. This whole solution not only looks heavy but also ugly, so I want to change it. I am interested in an elegant solution, so any help/guidance is welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半仙 2024-12-12 06:39:21

使用给定的信息:

  • ID必须是唯一的
  • ID必须是数字
  • ID不得表示顺序串联
  • ID不会由用户输入

PHP函数


** 编辑 **

是的,uniqid将返回一个接缝的顺序编号,但是我们可以轻松解决这个问题。考虑此代码,

class IDGenerator {
   //const BIT_MASK = '01110011';

   static public function generate() {

      $id = uniqid();

      $id = base_convert($id, 16, 2);
      $id = str_pad($id, strlen($id) + (8 - (strlen($id) % 8)), '0', STR_PAD_LEFT);

      $chunks = str_split($id, 8);
      //$mask = (int) base_convert(IDGenerator::BIT_MASK, 2, 10);

      $id = array();
      foreach ($chunks as $key => $chunk) {
         //$chunk = str_pad(base_convert(base_convert($chunk, 2, 10) ^ $mask, 10, 2), 8, '0', STR_PAD_LEFT);
         if ($key & 1) {  // odd
            array_unshift($id, $chunk);
         } else {         // even
            array_push($id, $chunk);
         }
      }

      return base_convert(implode($id), 2, 36);
   }
}

echo IDGenerator::generate();

该代码将带来结果,

ivpa493xrx7
d173barerui
evpoiyjdryd
99ej19mnau2

因为没有任何添加或修改的代码,除了整理位置外,不应有任何重复的值,而且一切似乎都是随机的。瞧!

** UPDATE(2014-02-24)**

我自最初发布的时间以来更新了此代码。您可能会发现修订版在这里

With the given information :

  • id must be unique
  • id must not be numeric
  • id must not represent a sequential series
  • id will not be input by the user

The PHP function uniqid is exactly what you need. Though it returns a 13 character long hexadecimal value.


** Edit **

Yes, uniqid will return a seamingly sequential number, but we can get around this easily. Consider this code

class IDGenerator {
   //const BIT_MASK = '01110011';

   static public function generate() {

      $id = uniqid();

      $id = base_convert($id, 16, 2);
      $id = str_pad($id, strlen($id) + (8 - (strlen($id) % 8)), '0', STR_PAD_LEFT);

      $chunks = str_split($id, 8);
      //$mask = (int) base_convert(IDGenerator::BIT_MASK, 2, 10);

      $id = array();
      foreach ($chunks as $key => $chunk) {
         //$chunk = str_pad(base_convert(base_convert($chunk, 2, 10) ^ $mask, 10, 2), 8, '0', STR_PAD_LEFT);
         if ($key & 1) {  // odd
            array_unshift($id, $chunk);
         } else {         // even
            array_push($id, $chunk);
         }
      }

      return base_convert(implode($id), 2, 36);
   }
}

echo IDGenerator::generate();

Which will give results like

ivpa493xrx7
d173barerui
evpoiyjdryd
99ej19mnau2

Since there is nothing added or modified, except shuffling the bits around, there should not be any duplicated values and everything seems random. Voilà!

** Update (2014-02-24) **

I update this piece of code since the time it was originally posted. You may find the revised version here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文