我有一个clj文件:
;; stringparity.clj ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(ns stringparity)
(defn get-java-string [input]
(.getBytes input "UTF-8"))
一个cljs文件:
;;; stringparity.cljs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(ns stringparity
(:import goog.crypt))
(defn get-js-string [input]
(goog.crypt.stringToUtf8ByteArray input))
以下代码不可执行,因为get-js-string
仅适用于javascript,get-java-string
适用于java;我只是假装你可以在同一台机器上运行它们来说明出了什么问题。使用“简单”字符串时,这两个函数都可以正常工作,但在使用""
这样的“复杂”字符串时会失败。我希望能够在clojure或clojurescript上散列任何字符串,并使它们的散列相同。为了做到这一点,我需要能够将javascript或java字符串转换为其等效的字节数组。似乎我在clojure和clojurescript方面都使用UTF-8,但是它们不会生成相同的字节数组(它们甚至不是相同的长度)。如何为clojure和clojurescript中的任何两个等效字符串生成完全相同的字节数组。
(= (seq (get-js-string "hello")) [104, 101, 108, 108, 111]
(seq (get-java-string "hello") [104, 101, 108, 108, 111]))
(= (seq (get-js-string ""))
;; when in cljs, get-js-string evaluates to the following
[237 160 180 237 188 134]
(seq (get-java-string ""))
;; when in clj, get-java-string evaluates to the following
[-16 -99 -116 -122])
答案 0 :(得分:4)
javascript implementation与[{3}}
不会properly handle个字符答案 1 :(得分:3)
goog.crypt.stringToUtf8ByteArray
无法处理在Javascript字符串中表示为“代理对”的字符(例如您的“”示例)并产生不正确的结果。
如果您不需要UTF-8但只需要一系列字节值来生成散列,则可以选择在两种情况下将字符编码为UTF-16字节序列:
cljs:
(defn to-byte [n] (if (>= n 128) (- n 256) n))
(defn get-js-string [input]
(map to-byte
(mapcat
#(let [u (.charCodeAt input %)]
[(-> (bit-and u 0xFF00) (bit-shift-right 8)) (bit-and u 0xFF)])
(range (.-length input)))))
CLJ:
(defn get-java-string [input]
(.getBytes input "UTF-16BE"))
在这两种情况下,这应该为您的示例字符串提供序列(-40 52 -33 6)
。