数値からランダムな文字列を作る

ランダムな文字列を作りたかったので, 色々とググってでてきた方法をEmacs Lispに実装してみた.

(defun my-integer-to-string (num &optional switch)
  "引数`num'に与えられた数値をランダムな文字列に変換する関数.
ランダムな文字列は, 数字とアルファベット小文字の範囲となっている.
オプショナル引数`switch'にalphが指定されていると,
範囲はアルファベット小文字だけとなる.
数値の変換には, 10進数からn進数へ変換する方法を使っている."
  (let ((old-num num) (leave 0)
        (num-list nil) (result "")
        base)
    (cond
     ((eq switch 'alph) (setq base 26))
     (t (setq base 36)))
    (while (not (= num 0))
      ;; cl-macを使って, psetqを使った方が楽
      (setq num (/ num base)
            leave (% old-num base)
            old-num num)
      (cond
       ((eq switch 'alph)
        (setq leave (char-to-string (+ leave ?a))))
       (t (when (> leave 9)
            (setq leave (char-to-string (+ leave (- ?a 10)))))))
      (setq num-list (cons leave num-list)))
    ;; list => string
    (dolist (i num-list)
      (setq result (concat result (format "%s" i))))
    result))


数値を29bitまでしか扱えないから, numに与える数値をデカくしすぎると溢れてくれる.
そのため, あんまり長い文字列は生成できない.

追記


plusさんによるバージョンです.
コードが簡潔でかつ綺麗になっています.

(defun my-integer-to-string (num &optional switch)
  "引数`num'に与えられた数値をランダムな文字列に変換する関数.
ランダムな文字列は, 数字とアルファベット小文字の範囲となっている.
オプショナル引数`switch'にalphが指定されていると,
範囲はアルファベット小文字だけとなる.
数値の変換には, 10進数からn進数へ変換する方法を使っている."
  (let ((base (if (eq switch 'alph) 26 36))
        (num-list nil)
        leave)
    (while (/= num 0)
      (setq leave (% num base)
            num (/ num base)
            num-list (cons (+ leave (cond
                                     ((eq switch 'alph)
                                      ?a)
                                     ((>= leave 10)
                                      (- ?a 10))
                                     (t
                                      ?0)))
                           num-list)))
    (concat num-list)))

更新時刻

  • 1かいめ 2007年, 12月17日, 4:23
  • 2かいめ 2007年, 12月22日, 3:49