我们刚刚通过万圣节,它是... 生活n00bs的夜晚!
我只有几天的时间在Clojure编程下。这项工作更接近于“真正的”Clojure,至少它是编译的。它也会产生一个结果,但可能不是正确的结果。更多在此之后:
(ns erikcw)
(defn toHex8 [n] (format "%08x" n)) ; Just a guess!
; can't use str, that's predefined.
(defn calculateChecksum [url] ; I renamed the arg to url so I can use strn later.
(loop [strn url ; this will loop over chars in strn.
hash (cycle "bjytk3lfj%3jklDskj") ; now hash repeats for as long as you need it.
key 1690912] ; modifying key along the way.
(prn strn key) ; debug print.
(let [k2 (bit-xor (bit-xor key (int (first hash))) (int (first strn)))
k3 (bit-or (bit-shift-right k2 23) (bit-shift-left k2 9))]
(if (empty? (rest strn))
(str "8" (toHex8 (bit-shift-right k3 8)) (toHex8 (bit-and k3 255)))
(recur (rest strn) (rest hash) k3)))))
(prn (calculateChecksum "HowNowBrownCow"))
我不知道toHex8
函数做什么,所以我写了,它打印为8位十六进制数字参数的函数。只是为了让dang的东西编译。
我不是使用索引从hash
和strn
中提取字符,而是将它们当作字符序列处理,并且仅在每次迭代中处理其头元素。 hash
是无限长的,由于(cycle)
。
位操作的名称以“bit-
”开头。
由于整数在Clojure中可以变得任意大,因此由于<< 9
,每个字符的结果数量会变得更大。这可能不是有意的。
无论如何,一些spoilsport只是发布了什么可能是正确答案。尽管如此,这很有趣,我希望我能与你分享一些努力。
编辑:因为戴夫射线使用(reduce)
坚持,我做了另一种解决方案:
(defn next-key [key str-hash]
(let [str1 (first str-hash)
hash1 (second str-hash)
k2 (bit-xor (bit-xor key hash1) str1)]
(bit-or (bit-shift-right k2 23) (bit-shift-left k2 9))))
(defn calculateChecksum2 [url]
(let [kk
(reduce next-key 1690912
(partition 2 ; (72 98) (111 106) (119 121) ...
(map int ; 72 98 111 106 119 121
(interleave url (cycle "bjytk3lfj%3jklDskj"))))) ; "HbojwyNt..."
]
(str "8" (toHex8 (bit-shift-right kk 8)) (toHex8 (bit-and kk 255)))))
(prn (calculateChecksum2 "HowNowBrownCow"))
这一个是有点更容易阅读,无需循环。 next-key
可能已被拖入主要功能,但我发现更容易理解这样的事情。
我们有一个哈希值列表和一个字符串值。为了使reduce
工作,我不得不把它们压缩成一个单一的列表;看评论。
我们仍然有一个问题,即原始算法不适用于无限大小的整数,再加上最后一行中可能的括号问题。你可能想要构建你自己的截断比特旋转函数。
什么是url.length()?它应该是str? – 2009-11-16 20:19:03
什么是url变量和hx8做什么? – jitter 2009-11-16 20:19:34
我不知道Clojure,所以我不会写一个答案,但你想reduce函数:http://clojure.org/api#reduce – 2009-11-16 20:49:16