首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生成具有非重复字符的单词列表的Shell脚本

生成具有非重复字符的单词列表的Shell脚本
EN

Stack Overflow用户
提问于 2018-02-24 22:34:59
回答 1查看 574关注 0票数 1

我找到一个lisp程序。它起作用了,但我也不太需要它。它的输出如下:

代码语言:javascript
复制
2323232323235ve3
2323232323235ve4
2323232323235ve5
2323232323235ve6

我需要做一个单词列表,用Base32字符显示16个字符,单词中有不重复的字符。然后,我需要在单词中添加.txt

代码语言:javascript
复制
asdfjklwert7csui.txt
jcfklinesftw8se3.txt

然后,我需要SHA512这个词,并检查一个已知的散列。

是否可以只输出与已知的散列匹配的单词?

以下是LISP源

代码语言:javascript
复制
#!/usr/bin/clisp

(defparameter *character-set* "234567abcdefghijklmnopqrstuvwxyz")
;(defparameter *character-set* "ABC")     ; < --- this line is for testing

(defparameter *word-length* 16)
;(defparameter *word-length* 4)           ; < --- this line is for testing

(defparameter *character-list*
       (coerce *character-set* 'list))

(defun final-char (in-string)
   (cond
      ((> (length in-string) 0)
         (elt in-string (1- (length in-string))))
      (t
         nil)))

(defun new-char-list (in-string)
   (let ((result))
      (mapcar
         (lambda (candidate)
            (cond
               ((not (eql candidate (final-char in-string)))
                  (push candidate result))))
         *character-list*)
      (nreverse result))
      )

(defun extend-string (in-string desired-length)
   (mapcar
      (lambda (new-char)
         (let ((new-string (concatenate 'string in-string (string new-char))))
            (cond
               ((>  (length new-string) desired-length))
               ((>= (length new-string) desired-length)
                  (format t "~a~%" new-string))
               (t
                  (extend-string new-string desired-length)))))
      (new-char-list in-string)))

(extend-string "" *word-length*)

Bash脚本输出到文件中,如下所示。我需要输出是更低的情况。

代码语言:javascript
复制
K5SMKLK5W85T6GTC
RZJRNV0VO1LVIMEM
RPSW59OPQLUBJKC5

这是Bash脚本

代码语言:javascript
复制
#!/bin/bash
ascii=
index=0
noNames=16                                              #No of names to generate
nameLength=10                                           #Length to generate (you said 10)
for(( i=65; i<=90; i++ ))                               #Add upper-case letters to 'ascii'
do
        ascii[$index]=$(echo $i | awk '{printf("%c",$1)}')
        index=$(( $index + 1 ))
done

for(( i=48; i<=57; i++ )) # Add numbers to 'ascii'
do
        ascii[$index]=$(echo $i | awk '{printf("%c",$1)}')
        index=$(( $index + 1))
done

for(( i=0; i<$noNames; i++))
do
    name=                                           #We'll store the name in here
    last=                                           #We'll store the index of the last 
                                                        #   character generated here
    for(( j=0; j<$nameLength; j++))
    do  
        num=$(( $RANDOM % $index ))             # Pick a random character index
        while [[ $num -eq $last ]]              #If it's the same as the last 
                                                        #  one...
        do
            num=$(( $RANDOM % $index ))     #... pick a new one!
        done
        last=$num                               #Update "last" to current value
            name=${name}${ascii[$num]}              #Add the correct letter to our name
    done
    echo "${name}"                                  #Print name...
done > output                                           #...to our output file
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-25 20:16:21

下面是一个用SBCL测试的通用Lisp答案。由于您需要计算哈希,所以我将使用一个名为铁皮的外部库。为了安装它,首先要安装安装Quicklisp。然后:

代码语言:javascript
复制
(ql:quickload :ironclad)

此部分可定制:

代码语言:javascript
复制
(defparameter *character-set* "234567abcdefghijklmnopqrstuvwxyz")
(defparameter *suffix* ".txt")

辅助功能

现在,我们将映射所有可能的字符串,这些字符串尊重您的约束(没有相同的连续字符)。我们也要把这些字符串作为字节来处理,因为硬的只能从字节的向量中计算散列。没有必要分配这么多字符串,只需一遍又一遍地重用同一个缓冲区:

代码语言:javascript
复制
(defun make-buffer (size)
  (concatenate '(vector (unsigned-byte 8))
               (make-array size :element-type '(unsigned-byte 8))
               (ironclad:ascii-string-to-byte-array *suffix*)))

以上所述分配所需的字节向量,同时考虑到后缀,转换为字节。下面,我们将对字符集进行同样的操作,该字符集也被强制作为一个列表(为了能够使用DOLIST):

代码语言:javascript
复制
(defun make-character-set ()
  (coerce (ironclad:ascii-string-to-byte-array *character-set*)
          'list))

我们还希望能够将散列字符串转换为字节向量,但也可以直接接受向量。以下函数确保将给定的值转换为所需的类型:

代码语言:javascript
复制
(defun ensure-hash (hash-designator)
  (etypecase hash-designator
    (string (ironclad:hex-string-to-byte-array hash-designator))
    (vector (coerce hash-designator '(vector (unsigned-byte 8))))))

查找散列

现在,我们可以找到一个哈希给定一组生成的单词。SIZE参数指示在后缀之前有多少个字符,而HASH-DESIGNATOR是十六进制表示法中的字符串,或者是一个字节向量:

代码语言:javascript
复制
(defun find-hash (size hash-designator)
  (let ((hash (ensure-hash hash-designator))
        (buffer (make-buffer size))
        (character-set (make-character-set)))
    (labels ((level (depth forbidden)
               (cond
                 ((>= depth size)
                  (when (equalp hash (ironclad:digest-sequence
                                      'ironclad:sha512 buffer))
                    (return-from find-hash
                      (values (map 'string #'code-char buffer)
                              buffer))))
                 (t (let ((next (1+ depth)))
                      (dolist (c character-set)
                        (unless (= c forbidden)
                          (setf (aref buffer depth) c)
                          (level next c))))))))
      (level 0 0))))

局部level函数的一般情况是根据字符集将字符设置在缓冲区中的depth位置,而忽略禁止字符,这是设置的最后一个字符(或最初为零)。当level到达size时,我们将单词作为字节向量存储在缓冲区中。在这种情况下,我们对这个单词进行散列,并将其与所需的散列进行比较。如果匹配,我们将字节数组(字符代码)转换为字符串,并返回内部缓冲区(它已经计算过了,也许可以重用)。

示例

代码语言:javascript
复制
(find-hash 3 "ddd2379f9a1adf4f0afa0befafdb070fb942d4d4e0331a31d43494149307221e5e699da2a08f59144b0ed415dea6f920cf3dab8ca0b740d874564d83b9b6f815")
=> "zyc.txt"
   #(122 121 99 46 116 120 116)

然而,由于指数复杂性,对于16个字符来说,这项任务将是不切实际的:

代码语言:javascript
复制
> (time (find-hash 4 #(0)))
Evaluation took:
  1.679 seconds of real time
  1.676000 seconds of total run time (1.672000 user, 0.004000 system)
  [ Run times consist of 0.028 seconds GC time, and 1.648 seconds non-GC time. ]
  99.82% CPU
  4,019,832,288 processor cycles
  899,920,096 bytes consed

NIL

> (time (find-hash 5 #(0)))
Evaluation took:
  51.768 seconds of real time
  51.796000 seconds of total run time (51.684000 user, 0.112000 system)
  [ Run times consist of 0.952 seconds GC time, and 50.844 seconds non-GC time. ]
  100.05% CPU
  123,956,130,558 processor cycles
  27,897,672,624 bytes consed
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48976038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档