/ / Helfen Sie bei der Übersetzung dieses Java-Codeblocks in Clojure? - Java, Funktionsprogrammierung, Clojure

Helfen Sie bei der Übersetzung dieses Java-Codeblocks in Clojure? - Java, Funktionsprogrammierung, Clojure

Ich werde mit meinen Füßen nass Clojureund versuchen, sich an die funktionale Programmierung zu gewöhnen.

Ich habe verschiedene Imperative übersetztFunktionen aus anderen Sprachen in ihre Clojure-Entsprechungen - und bis jetzt ist alles gut gelaufen. Allerdings bin ich jetzt auf einen Knackpunkt gestoßen und habe keine Ahnung, wie ich diese Java-Methode in idiomatische Clojure übersetzen soll.

Anfangs schien "map" das richtige Werkzeug zu sein, aber nachdem ich ein bisschen damit gespielt habe, bin ich mir nicht so sicher. Kann mir jemand zeigen, wie man diese Funktion in Clojure schreibt?

Vielen Dank!

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);

}

Antworten:

7 für die Antwort № 1

Wir sind gerade hinter Hallow, und es ist ... die nacht der lebenden n00bs!

Ich habe nur ein paar Tage Zeit für die Programmierung von Clojureunter meinem gürtel. Diese Anstrengung kommt der "echten" Clojure näher und wird zumindest kompiliert. Es erzeugt auch ein Ergebnis, aber wahrscheinlich nicht das richtige. Mehr danach:

(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"))

Ich weiß nicht, was toHex8 funktioniert, also habe ich eine Funktion geschrieben, die ihr Argument als 8-stellige Hex-Zahl ausgibt. Nur um das Mistding zum Kompilieren zu bringen.

Anstatt einen Index zu verwenden, um Zeichen herauszuholen hash und strnIch behandle beide als Zeichenfolgen und behandle in jeder Iteration nur deren Kopfelemente. hash ist unendlich lang, dank (cycle).

Die Bitoperationen haben Namen, die mit "bit-".

Da in Clojure ganze Zahlen beliebig groß werden können, wird die resultierende Zahl mit jedem Zeichen größer << 9. Das ist wahrscheinlich nicht beabsichtigt.

Wie auch immer, einige Spielverderber haben gerade geschrieben, was wahrscheinlich ein Spiel werden wird richtig Antworten. Trotzdem hat es Spaß gemacht, ich hoffe, ich konnte ein wenig von der Anstrengung mit Ihnen teilen.

Bearbeiten: Weil Dave Ray darauf besteht, etwas zu benutzen (reduce)Ich habe eine andere Lösung gemacht:

(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"))

Dieser ist etwas leichter zu lesen und benötigt keine Schleife. next-key hätte in die Hauptfunktion hineingezogen werden können, aber ich finde die Dinge so einfacher zu verstehen.

Wir haben eine Liste von Hash-Werten und einen von String-Werten. Zu machen reduce Ich musste sie zu einer einzigen Liste zusammenfassen. Zeige Kommentare.

Wir haben immer noch das Problem, dass das OriginalDer Algorithmus sollte nicht mit Ganzzahlen von unbegrenzter Größe sowie einem möglichen Klammerungsproblem in der letzten Zeile arbeiten. Möglicherweise möchten Sie Ihre eigenen Bit-Twiddling-Funktionen zum Abschneiden erstellen.


1 für die Antwort № 2

Clojure macht den Operator >>> nicht verfügbar, sodass keine direkte Übersetzung möglich ist.