帮助将此Java代码块转换为Clojure?

时间:2009-11-16 20:14:02

标签: java functional-programming clojure

我正忙着Clojure,试图习惯功能编程。

我一直在将各种命令功能从其他语言翻译成他们的Clojure等价物 - 到目前为止,一切进展顺利。但是,我现在遇到了一个棘手的问题,我不知道如何将这种Java方法转换为惯用的Clojure。

起初“地图”似乎是正确的工具,但在玩了一下之后我不太确定。有人能告诉我如何在Clojure中编写这个函数吗?

谢谢!

public String calculateChecksum(String str)
{
    String hash = "bjytk3lfj%3jklDskj";
    int key = 1690912;

    for(int i=0; i < str.length(); i++) {

        key = key ^ (int)(hash.charAt(i%hash.length()))^(int)(str.charAt(i));
        key = key>>>23|key<<9;

    }return "8"+toHex8(key>>>(8&255))+toHex8(key&255);

}

2 个答案:

答案 0 :(得分:7)

我们刚刚过了Hallow'een,而且...... 活着的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位十六进制数。只是为了得到编辑的东西。

我不是使用索引从hashstrn中提取字符,而是将它们视为字符序列,并在每次迭代中只处理它们的头元素。由于hash(cycle)无限长。

位操作的名称以“bit-”开头。

因为在Clojure中整数会变得任意大,所以由于<< 9,每个字符的结果数会变得更大。这可能不是故意的。

无论如何,一些spoilsport刚刚发布了可能是正确的答案的内容。不过,这很有趣,我希望我能与你分享一些努力。

编辑:由于Dave Ray坚持使用(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工作,我必须将它们压缩成一个列表;见评论。

我们仍然遇到这样的问题:原始算法不适用于无限大小的整数,以及最后一行可能的括号内问题。您可能希望构建自己的截断位功能。

答案 1 :(得分:1)

Clojure不公开&gt;&gt;&gt;运营商,因此无法直接翻译。