7 返信 最新の回答 日時: Jan 30, 2014 8:50 PM ユーザー:Nu-nrg

    英数字のみを使用した一意の値を生成したい

    Nu-nrg

      タイトル

      英数字のみを使用した一意の値を生成したい

      フォーラムに投稿

           WEBのURIでも利用したい、Filemakerから作成する、一意の値を英数字の小文字のみで(文字数をあらかじめ決めた)、ランダムで生成する方法で何か良い方法がありますでしょうか。

        • 1. Re: 英数字のみを使用した一意の値を生成したい
          hiro_

               「絶対一意」の保障は出来ませんが、ランダムに生成する式例、

               Let([
                $桁数=8; // 桁数を指定
                $候補="1234567890abcdefghijklmnopqrstuvwxyz"; // 許可する文字候補を指定
                $候補数=Length($候補);
                $関数="Middle($候補;Int(Random*$候補数+1);1) & ";
                $関数=Substitute(10^$桁数-1;9;$関数) &  "\"\""
               ];
                Evaluate($関数)
               )

          • 2. Re: 英数字のみを使用した一意の値を生成したい
            Shin

                 何桁必要で、最終的に何個生成するかによって、一意の保証が変わります。

                 例えば12桁必要で、100万個程度必要ならば、適当な値から始まるシリアル値を作っておいて、Hiroさんの式で得られるような文字列textに対して、シリアル値に依存する文字を付け加えます。例えば

                 Let (
                 [
                  ch = "0123456789abcdefghijkl,mopqrstuvwxyz" ;
                  c0 = Mod ( serial ; 38 ) + 1 ;
                  c1 = Mod ( Div ( serial ; 38 ) ; 38 ) + 1 ;
                  c2 = Mod ( Div ( serial ; 38 ^ 2 ) ; 38 ) + 1 ;
                  c3 = Mod ( Div ( serial ; 38 ^ 3 ) ; 38 ) + 1
                 ] ;
                  Middle ( ch ; c0 ; 1 )
                  & Middle ( text ; 1 ; 2 )
                  & Middle ( ch ; c3 ; 1 )
                  & Middle ( text ; 3 ; 3 )
                  & Middle ( ch ; c1 ; 1 )
                  & Middle ( text ; 7 ; 2 )
                  & Middle ( ch ; c2 ; 1 )
                 )

                 これで38^4までは一意が保証されます。

                 chは乱数で並び替えた文字列にしておくと、さらに規則性が見えなくなるでしょう。

                  

            • 3. Re: 英数字のみを使用した一意の値を生成したい
              sago350@未来Switch

                   Ver12以降であればGet( UUID )という関数を使って絶対に重複しないテキストを生成できます。

                   Get( UUID ) → FBDAE551-1D25-45ED-A79E-A118FCC64069

                   といった文字列を返すので、それをテキスト関数で料理すると

                   Substitute ( Lower ( Get( UUID ) ) ; "-"; "" ) → fbdae5511d2545eda79ea118fcc64069

                   となります。
                   文字数は32文字に固定になってしまいますが、文字数がただ決まった長さであればいいのでしたら、この方法で。
                    

              • 4. Re: 英数字のみを使用した一意の値を生成したい
                hiro_

                     Get(UUID)はユニーク担保されますが、一方で、
                     16進数値を返すので、文字候補も16文字(0123~9ABCDEF)に限定で、
                     桁数も32桁(128ビット)に固定なことから、
                     質問者さんの意向はどうかしら?

                • 5. Re: 英数字のみを使用した一意の値を生成したい
                  Nu-nrg

                       みなさま、ありがとうございました。
                       教えていただいた計算式の解読に時間が必要です(笑)
                       検証してまたご連絡します。

                       Get(UUID)は便利ですね、しかしURIとして固定するソースの情報としては長過ぎると思います。
                       何文字にするか決めるのが先ですかね。
                       文字数から生成できる個数で考えるべきでしょうか、一考いたします。

                       取り急ぎお礼まで。

                  • 6. Re: 英数字のみを使用した一意の値を生成したい
                    Shin

                         Get ( UUID ) は、連続して出してみるとわかるのですが、似たような文字列が生成されていきます。目的に依って使い分けないと行けないでしょうね。

                         これを数値に戻して、計算の種にする、という方法は有効かも。

                         まあ、どこまで一意を保証しないといけないか、似た文字列でいいか、でしょう。

                    • 7. Re: 英数字のみを使用した一意の値を生成したい
                      Nu-nrg

                           Get ( UUID )のように16進数で考えると、8桁(8bit)で、4,294,967,296 通り。
                           数字のみの10進数、8bitで1億通り。

                           16進数、6bitで16,777,216通り
                           10進数、6bitで百万通り。

                           URIの一意の識別子で使うなら、英数字混じっていたほうが良さそうで、
                           16進数の8桁あれば十分な数で、コードとかで利用するのも楽な桁かなと思います。