摘要:的解法程序猿的世界,代碼說明一切,我們直接上代碼吧,算法的入口是一個名為函數(shù)不知道能完全看懂上面代碼的人有多少。程序猿的語言世界真的好復(fù)雜
首先聲明一點,這篇短文不是要挑起語言之間的關(guān)于孰優(yōu)孰劣的論戰(zhàn),只是希望通過一個小需求,讓大家能夠?qū)Ρ润w會一下函數(shù)式編程和面向?qū)ο缶幊痰牟町悾òɡ砟詈驼Z法上的)。
要解決一個什么問題
Clojure 是什么?
Clojure 是運行在 Java 虛擬機(JVM)上的一種 Lisp 方言,她比 Common Lisp 更強調(diào)純函數(shù)式編程,同時擁有復(fù)雜的「宏」。具體可以看 CSDN 上的一篇介紹文章 現(xiàn)實世界的LISP:Clojure語言初探 和知乎上的討論 請評價一下Clojure語言的設(shè)計
我們在開發(fā)過程中經(jīng)常會碰到這個需求,要對一個字符串進行哈希,然后當(dāng)成 key 存入 redis。我們準(zhǔn)備使用 Java 的 SHA-512 哈希算子來做第一步運算,并且把結(jié)果再做一次 Base64 編碼轉(zhuǎn)換。
好的,那我們接下來就看看在兩種語言中如何做到這一點吧。
Clojure 的解法程序猿的世界,代碼說明一切,我們直接上代碼吧,算法的入口是一個名為 hash-name 函數(shù):
(defonce ^:private hash-key "universal_redis_hash_key") (defn hash-name [k] (.substring ^String (:password (digest hash-key k)) 0 4)) (defn digest ([salt passwd] (digest "SHA-512" 512 salt passwd)) ([hashalg iterations salt passwd] (let [jhash (MessageDigest/getInstance hashalg) new-pass (b64-encode (digester jhash salt passwd iterations))] {:salt salt :password new-pass}))) (defn- digester [^MessageDigest hasher ^String salt ^String pw-clear iter] {:tag String} (letfn [(hashme [hv] (letfn [(oneround [hv] (do (.reset hasher) (.digest hasher hv)))] (nth (iterate oneround hv) iter)))] (.reset hasher) (.update ^MessageDigest hasher (.getBytes salt)) (.update ^MessageDigest hasher (.getBytes pw-clear)) (hashme (.digest hasher)))) (defn b64-encode [^bytes b] {:tag String} (Base64/encodeBase64String b))
不知道能完全看懂上面代碼的人有多少。要是我們用Java寫出來的話,相信很多人會拍著腦袋:原來如此!
Java 的解法還是一樣,直接上代碼,這里只有一個函數(shù) hashName:
private final static String hashKey = “universal_redis_hash_key"; public static String hashName(String salt, String pw, int iter) { try { MessageDigest digest = MessageDigest.getInstance("SHA-512"); digest.reset(); digest.update(salt.getBytes()); digest.update(pw.getBytes()); byte[] temp = digest.digest(); for (int i = 0; i < iter; i++) { digest.reset(); temp = digest.digest(temp); } String result = Base64.encodeBase64String(temp); return result.substring(0, 4); } catch (Exception ex) { ex.printStackTrace(); } return ""; }結(jié)論
對這兩門語言的看法,或許有人會從通俗易懂上進行比較,有人會從優(yōu)雅嚴(yán)謹(jǐn)性上進行批判,我沒有任何傾向性,這就是一個仁者見仁智者見智的問題。
我只想補充說一下這種對比的由來。我司的程序員中 Clojure 粉較多,很多程序都是用 Clojure 寫的。最近要跟其他公司的小伙伴合作搭一個服務(wù),兩邊都需要采用同樣的關(guān)鍵字哈希算法。我找到一塊我們的實現(xiàn)片段,發(fā)了過去。但是對方不懂 Clojure,他們使用的是 Ruby;我懂 Clojure 但是不懂 Ruby,兩個人都快沒法交流了。最后我們一商量,大家都能懂 Java,所以我先把 Clojure 代碼翻譯成 Java 代碼,然后他再轉(zhuǎn)換成 Ruby 代碼,這樣兩邊的系統(tǒng)就對接上了。程序猿的語言世界真的好復(fù)雜!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64123.html
摘要:我們的目標(biāo)是建立對每一種語言的認(rèn)識,它們是如何進化的,未來將走向何方。有點的味道是堅持使用動態(tài)類型,但唯一還收到合理擁泵的編程語言,然而一些在企業(yè)的大型團隊中工作的開發(fā)者擇認(rèn)為這會是的一個缺陷。 為什么我們需要如此多的JVM語言? 在2013年你可以有50中JVM語言的選擇來用于你的下一個項目。盡管你可以說出一大打的名字,你會準(zhǔn)備為你的下一個項目選擇一種新的JVM語言么? 如今借助來自...
摘要:如果應(yīng)用發(fā)生了內(nèi)存泄漏問題,就會進行檢測生成報告,并且提供切實可行的方案去掉這個問題。主要特性實時的內(nèi)存泄漏檢測和告警一份包含時間,內(nèi)存大小,速度以及泄漏事件的重要級別的報告。 在這篇文章中我們決定收集制作一個關(guān)于這類工具的簡略名單,他們中的大多數(shù)工具只是最近推出的。其中一些工具是為Java定制的,但也有一些是支持其他語言。但對于Java項目而言,他們都是非常好的,并且擁有同一個愿景:...
摘要:根據(jù)對社區(qū)和新特性的深刻理解,他創(chuàng)作了函數(shù)式編程一書。問你在倫敦社區(qū)的經(jīng)歷是否幫助你創(chuàng)作了函數(shù)式編程這本書絕對是這樣。我認(rèn)為引入函數(shù)式編程會為很多編程任務(wù)提供方便。問之前的是面向?qū)ο蟮?,現(xiàn)在全面支持函數(shù)式編程。 非商業(yè)轉(zhuǎn)載請注明作譯者、出處,并保留本文的原始鏈接:http://www.ituring.com.cn/article/199271 Richard Warburto...
摘要:而且這種現(xiàn)象在德國的法定節(jié)假日里更加突出。所以本文提到的這些東西都是在德國節(jié)假日里無聊的產(chǎn)物,對于顧問的實際工作可能幫助不大。這也是在這篇文章里介紹的眾多用搞出來的無聊的東西里唯一被官方認(rèn)可的工具,囧。直接用執(zhí)行里的事務(wù)碼或者函數(shù)。 國慶大假馬上就要來臨了,我們聊點輕松的話題,關(guān)于假期。 Jerry的成都同事李貝寧(Li Ben), 《SAP成都研究院李三郎:SCP Applicati...
摘要:第一節(jié)函數(shù)式范式什么是函數(shù)式編程函數(shù)式編程英語或稱函數(shù)程序設(shè)計,又稱泛函編程,是一種編程范型,它將電腦運算視為數(shù)學(xué)上的函數(shù)計算,并且避免使用程序狀態(tài)以及易變對象。 第一節(jié) 函數(shù)式范式 1. 什么是函數(shù)式編程 函數(shù)式編程(英語:functional programming)或稱函數(shù)程序設(shè)計,又稱泛函編程,是一種編程范型,它將電腦運算視為數(shù)學(xué)上的函數(shù)計算,并且避免使用程序狀態(tài)以及易變對...
閱讀 3929·2021-09-10 11:22
閱讀 2419·2021-09-03 10:30
閱讀 3716·2019-08-30 15:55
閱讀 2030·2019-08-30 15:44
閱讀 884·2019-08-30 15:44
閱讀 635·2019-08-30 14:04
閱讀 3107·2019-08-29 17:18
閱讀 1319·2019-08-29 15:04