首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure等同于Python的编码(‘hex’)和解码(‘hex’)

Clojure等同于Python的编码(‘hex’)和解码(‘hex’)
EN

Stack Overflow用户
提问于 2012-04-08 20:57:59
回答 4查看 9.9K关注 0票数 14

在Clojure中,是否有一种惯用的方法将字符串编码和解码为十六进制?来自Python的示例:

代码语言:javascript
复制
'Clojure'.encode('hex')
# ⇒ '436c6f6a757265'
'436c6f6a757265'.decode('hex')
# ⇒ 'Clojure'

为了显示我的一些努力:

代码语言:javascript
复制
(defn hexify [s]
  (apply str
    (map #(format "%02x" (int %)) s)))

(defn unhexify [hex]
  (apply str
    (map 
      (fn [[x y]] (char (Integer/parseInt (str x y) 16))) 
      (partition 2 hex))))

(hexify "Clojure")
;; ⇒ "436c6f6a757265"

(unhexify "436c6f6a757265")
;; ⇒ "Clojure"
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-04-09 01:54:53

我相信您的unhexify函数是最常用的。但是,可以用一种更简单的方式编写hexify

代码语言:javascript
复制
(defn hexify [s]
  (format "%x" (new java.math.BigInteger (.getBytes s))))
票数 4
EN

Stack Overflow用户

发布于 2013-03-26 07:58:03

由于所有发布的解决方案都有一些缺陷,我在此分享我自己的:

代码语言:javascript
复制
(defn hexify "Convert byte sequence to hex string" [coll]
  (let [hex [\0 \1 \2 \3 \4 \5 \6 \7 \8 \9 \a \b \c \d \e \f]]
      (letfn [(hexify-byte [b]
        (let [v (bit-and b 0xFF)]
          [(hex (bit-shift-right v 4)) (hex (bit-and v 0x0F))]))]
        (apply str (mapcat hexify-byte coll)))))

(defn hexify-str [s]
  (hexify (.getBytes s)))

代码语言:javascript
复制
(defn unhexify "Convert hex string to byte sequence" [s] 
      (letfn [(unhexify-2 [c1 c2] 
                 (unchecked-byte 
                   (+ (bit-shift-left (Character/digit c1 16) 4)
                      (Character/digit c2 16))))]
     (map #(apply unhexify-2 %) (partition 2 s))))

(defn unhexify-str [s]
  (apply str (map char (unhexify s)))) 

优点:

十六进制结果wrappers

  • Handling 中专用performance

  • Generic前导为零的

字节流<-->字符串转换

票数 18
EN

Stack Overflow用户

发布于 2012-04-10 19:19:43

您的实现不适用于非ascii字符,

代码语言:javascript
复制
(defn hexify [s]
  (apply str
    (map #(format "%02x" (int %)) s)))

(defn unhexify [hex]
  (apply str
    (map 
      (fn [[x y]] (char (Integer/parseInt (str x y) 16))) 
        (partition 2 hex))))

(= "\u2195" (unhexify(hexify "\u2195")))
false ; should be true 

为了克服这个问题,您需要使用所需的字符编码来序列化字符串的字节,每个字符可以是多个字节。

这有一些“问题”。

  • 记住,所有的数字类型都是在JVM中有符号的。
  • 没有无符号字节。

在惯用的java中,你会使用一个整数的低位字节,并像这样屏蔽它,无论你在哪里使用它。

代码语言:javascript
复制
    int intValue = 0x80;
    byte byteValue = (byte)(intValue & 0xff); -- use only low byte

    System.out.println("int:\t" + intValue);
    System.out.println("byte:\t" + byteValue);

    -- output:
    -- int:   128
    -- byte:  -128

clojure有(unchecked-byte)可以有效地做到这一点。

例如,使用UTF-8可以执行以下操作:

代码语言:javascript
复制
(defn hexify [s]
  (apply str (map #(format "%02x" %) (.getBytes s "UTF-8"))))

(defn unhexify [s]
  (let [bytes (into-array Byte/TYPE
                 (map (fn [[x y]]
                    (unchecked-byte (Integer/parseInt (str x y) 16)))
                       (partition 2 s)))]
    (String. bytes "UTF-8")))

; with the above implementation:

;=> (hexify "\u2195")
"e28695"
;=> (unhexify "e28695")
"↕"
;=> (= "\u2195" (unhexify (hexify "\u2195")))
true
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10062967

复制
相关文章

相似问题

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