html – 奇怪的Base64編碼/解碼問題
我使用Grails 1.3.7.我有一些程式碼使用內建的base64Encode函式和base64Decode函式.在一些簡單的測試用例中,一切都可以正常工作,在這些情況下,我會對一些二進位制資料進行編碼,然後解碼生成的字串並將其寫入一個在這種情況下,檔案是相同的.
但是後來我寫了一個Web服務,將base64編碼的資料作為POST呼叫中的一個引數.儘管base64資料的長度與傳入函式的字串相同,但是base64資料的內容正在被修改.我花了DAYS除錯這個,最後寫了一個測試控制器,它將base64中的資料傳遞給post,並且使用正確的base64編碼資料的本地檔案的名稱,如:
data=AAA-base-64-data...&testFilename=/name/of/file/with/base64data
在測試函式中,我將輸入資料引數中的每個位元組與測試檔案中的相應位元組進行了比較.我發現輸入資料引數中的每個“”字元都被替換為“”(空格,序號ascii 32).咦?該怎麼辦?
為了確定我是對的,我補充說:
data = data.replaceAll(' ', '+')
並且確切地說,資料解碼完全正確.我嘗試了任意長的二進位制檔案,它現在每次都工作.但是,我不知道我的生活中將修改post的資料引數將ord(43)字元轉換為ord(32)?我知道這個加號是base64規格中兩個有點依賴平臺的字元之一,但是由於我現在在同一臺機器上進行編碼和解碼,所以我對此造成了很大的困惑.當然我有一個“修復”,因為我可以使它的工作,但我很緊張的“修復”,我不明白.
程式碼太大,不能在這裡釋出,但是我得到base64編碼如下:
def inputFile = new File(inputFilename) def rawData =inputFile.getBytes() def encoded = rawData.encodeBase64().toString()
然後我將編碼的字串寫入新的檔案,以便稍後使用它進行測試.如果我載入該檔案,所以我得到相同的rawData:
def encodedFile = new File(encodedFilename) String encoded = encodedFile.getText() byte[] rawData = encoded.decodeBase64()
所以這一切都很好.現在假設我使用“編碼”變數並將其新增到POST函式的引數中,如下所示:
String queryString = "data=$encoded" String url = "http://localhost:8080/some_web_service" def results = urlPost(url, queryString) def urlPost(String urlString, String queryString) { def url = new URL(urlString) def connection = url.openConnection() connection.setRequestMethod("POST") connection.doOutput = true def writer = new OutputStreamWriter(connection.outputStream) writer.write(queryString) writer.flush() writer.close() connection.connect() return (connection.responseCode == 200) ? connection.content.text : "error$connection.responseCode, $connection.responseMessage" }
在Web服務端,在控制器中我得到如下引數:
String data = params?.data println "incoming data parameter has length of ${data.size()}" //confirm right size //unless I run the following line, the data does not decode to the same source data = data.replaceAll(' ', '+') //as long as I replace spaces with plus, this decodes correctly, why? byte[] bytedata = data.decodeBase64()
對不起長期的咆哮,但我真的很想明白為什麼我必須做“替換空格加號”,以使其正確解碼.請求引數中使用的加號有什麼問題嗎?
無論什麼填充引數,希望請求是URL編碼的形式(具體來說,應用程式/ x-www-form-urlencoded,其中“”表示空格),但是沒有對其進行URL編碼.我不知道你的語言提供了什麼功能,但是在虛擬碼中,queryString應該被構建
concat(uri_escape("data"), "=", uri_escape(base64_encode(rawBytes)))
這簡化了
concat("data=", uri_escape(base64_encode(rawBytes)))
“”“字元將被替換為”+“.
http://stackoverflow.com/questions/5628738/strange-base64-encode-decode-problem