2014-12-01 46 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