2014-12-01 67 views
4

我有在编码串,并返回URL安全字符串C#的一段代码(即解码以后)C#等效的base64 + UrlTokenEncode的Clojure中

string stringToEncrypt = "Winter is coming"; 

byte[] bytes = new byte[stringToEncrypt.Length * sizeof(char)]; 
System.Buffer.BlockCopy(stringToEncrypt.ToCharArray(), 0, bytes, 0, bytes.Length); 

System.Web.HttpServerUtility.UrlTokenEncode(bytes).Dump(); 

Dump是从LinqPad。我用它来快速测试C#的代码片段

执行时返回VwBpAG4AdABlAHIAIABpAHMAIABjAG8AbQBpAG4AZwA1

我正试图从clojure服务做同样的事情。使用encode库和this answer去当我有

(String. (b64/encode (.getBytes email)) "UTF-8") 

我得到V2ludGVyIGlzIGNvbWluZw==,这是

  • 没有URL编码
  • 不匹配的C#版本。

尝试查看UrlTokenEncode()的MSDN文档,但没有太多的细节介绍它的实现,以便查看底层发生了什么。

我可以在clojure中生成等效字符串吗?

+0

你可以找到UrlTokenEncode [这里](HTTP的源代码:/ /www.dotnetframework.org/default.aspx/[email protected]@1/[email protected]@1/[email protected]@1/DEVDIV/depot/DevDiv/releases/whidbey/NetFXspW7/ndp/fx/src/xsp/System/Web/httpserverutility @ cs/1/httpserverutility @ cs) – 2014-12-01 18:49:10

+0

Ack。不知道为什么链接不工作。做一个谷歌搜索urltokenencode源,并点击dotnetframework.org链接。 – 2014-12-01 18:55:52

+0

@罗伯特哈维酷啊,当然,我当时看错了地方!谢谢。 – LocustHorde 2014-12-02 09:57:07

回答

3

感谢罗伯特指出UrlTokenEncode的来源。它执行以下操作:与填充字符(12)的数量

  1. 的Base64编码的输入字节
  2. 更换任何尾随填充=
  3. 替换+-/_

其他基本细节是C#示例编码字符串的UTF-16表示(每个字符2个字节)。为了说明这一点,这里是从转到操场一个例子:http://play.golang.org/p/UlKMa7_OwV

此代码产生预期的输出测试输入:

(ns blah.core 
    (:require [clojure.data.codec.base64 :as b64]) 
    (:require [clojure.string :as string]) 
    (:gen-class)) 

(defn encode [original] 
    (let [bytes_in (.getBytes original "UTF-16LE") 
     bytes_enc (b64/encode bytes_in) 
     bytes_len (alength bytes_enc) 
     pad_count (b64/pad-length bytes_enc 0 bytes_len) 
     enc_string (String. bytes_enc 0 (- bytes_len pad_count) "UTF-8") 
     enc_string (string/replace enc_string \+ \-) 
     enc_string (string/replace enc_string \/ \_)] 
     (str enc_string pad_count))) 

(defn -main 
    [& args] 
    (let [message "Winter is coming"] 
    (println message) 
    (println (encode message)))) 

DECODE函数就留给读者自己练习。

+0

谢谢,效果很好。 – LocustHorde 2014-12-02 10:37:08

+0

一个小改进就是处理空字符串的情况。 – 2014-12-02 16:22:56

2

如果您使用的是Java 8中,新Base64类,连同一个小模运算的平板计做的:

(defn url-token-encode [bytes] 
    (let [byte-count (count bytes)] 
    (if (pos? byte-count) 
     (str (.. (java.util.Base64/getUrlEncoder) (withoutPadding) (encodeToString bytes)) 
      (mod (- byte-count) 3)) 
     ""))) 

(defn encode [s] 
    (url-token-encode (.getBytes s "UTF-16LE"))) 

(encode "Winter is coming") 
;=>"VwBpAG4AdABlAHIAIABpAHMAIABjAG8AbQBpAG4AZwA1" 
+0

太好了,谢谢! – LocustHorde 2014-12-02 10:36:47