解字謎:黑白皆算,對我等眾猿而言中央C所在位置數優剃愛膚杠吧愛慕帝貳億次的值是?


題目:黑白皆算,對我等眾猿而言中央C所在位置數優剃愛膚杠吧愛慕帝貳億次的值是?

解:

1.破題

1.1黑白皆算,中央C所在位置(C do)

上圖是一個標准的鋼琴鍵盤示意圖。這句話的意思黑鍵也算,從第一個數中央C是第40個(每組12按鍵(7個白鍵+5個黑鍵,第一組前有3個按鍵)。

1.2 對我等眾猿而言

意思是從0開始索引,那么C do的位置值是39

1.3優剃愛膚杠吧 愛慕帝貳 貳億次 的值

這句話是諧音,實際指的的是 UTF-8 MD2 2億次的值。MD2是歷史悠久一個Hash加密算法,最初用於8位機這種嵌入式設備上,目前其安全性很低,不建議使用了。建議參考MD2算法作者原文上的測試結果,來驗證自己語言的加密算法。(網上搜到其作者92年寫的算法原文上面的C代碼我直接拷貝到clan中也照樣執行),Hash值這類算法一般輸入是一個字節數組。所以UTF-8的意思,以UTF-8編碼格式獲取39的字節編碼。2億次的意思就說循環加密2億次。實際上UTF-8對於此題沒有意義,對於0x00-0x7F之間的字符(包含數字字母),UTF-8編碼與ASCII編碼完全相同。

 

破題后就是寫代碼來計算了。

2.解題代碼

2.1Python

Python的代碼最為簡潔,我參考52pojie貼子:

from Crypto.Hash import MD2
if __name__ == '__main__':
#print_hi('PyCharm')
txt = "39"
# md2加密1億次
for i in range(200000000):
txt = MD2.new(txt.encode("utf8")).hexdigest()
print(txt)
需要Python環境安裝pycryptodome ,使用pip安裝 pip install pycryptodome。hexdigest()作為十六進制數據字符串值

2.2Java

需要導入apache.commons.codec庫。我建議建立Maven項目。這樣方便在線導入依賴。否則手工需要去官網下載jar包,再導入jar包。代碼書寫起來簡潔程度不亞於Python。

package com.company;
import org.apache.commons.codec.digest.DigestUtils;
public class Main {
public static void main(String[] args) {

String txt ="39";

// MD2
for(int i=0;i<200000000;i++){
/// public static byte[] md2(String data) {
// return md2(StringUtils.getBytesUtf8(data));
// }
txt= DigestUtils.md2Hex(txt);
}

System.out.println(hash);

}
}
 
        

2.3CSharp

C#的代碼最為麻煩,首先C#官方庫(System.Security.Cryptography)只有MD5加密算法,另外第三方收費庫Chilkat .NET包含MD2算法,但是價格太貴。還好Mono中有。需要通過Nuget在項目里安裝。再者C#加密類調用步驟都多一些,而且沒有直接字符輸出的功能。我這對此封裝了方法,一個是進行字符串輸出,一個是封裝加密計算過程。使得最終調用的風格和上述兩個代碼類似。

新建項目后,NutGet 搜索Mono.Security安裝。

using System;
using System.Text;
using Mono.Security.Cryptography;

namespace testdemo
{
class Program
{
static void Main(string[] args)
{
string txt = "39";
for (int i = 0; i < 200000000; i++)
{
txt = Md2Crypto(txt);
//Console.WriteLine($"{i:d9}:{txt}");
}
            Console.WriteLine($"{txt}");

}

public static string Md2Crypto(string source)
{
using (MD2 myMD2 = MD2.Create())
{
try
{
byte[] input = Encoding.UTF8.GetBytes(source);
byte[] output= myMD2.ComputeHash(input);

//string hashstr = GetHexStrByteArray(output);
return hashstr;

}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
/// <summary>
/// 官方文檔介紹為了hash后是需要核實后位十六進制字節數組,為了方便查看結果,格式化成2位十六禁止位的字符串
/// https://docs.microsoft.com/zh-cn/dotnet/api/system.security.cryptography.md5?view=netframework-4.8
/// ComputeHash類的方法將 MD5 哈希值作為16字節的數組返回。 請注意,某些 MD5 實現產生了32字符的十六進制格式的哈希。
/// 若要與此類實現進行互操作,請將方法的返回值格式化 ComputeHash 為十六進制值。
/// </summary>
/// <param name="array"></param>
/// <returns></returns>
public static string GetHexStrByteArray(byte[] array)
{
string result = "";
for (int i = 0; i < array.Length; i++)
{
//輸出2位的十六進制
result+=($"{array[i]:x2}");
}
return result;
}
}
}
 
        

3.測試源代碼下載及項目介紹 https://github.com/edzjx/Md2Crypto

 
        
參考引用
【1】MD2最初算法(C實現)The MD2 Message-Digest Algorithm
【2】52pojie提問帖 讀書成詩-謎題求解2 第91樓
【3】Java 加密庫官網 Apache Commons Codec
【4】參考網上的java MD2 demo Java MD2加密算法
【5】使用Mono加密庫官網介紹 Cryptography
【6】參考CSharp Cryptography庫使用代碼(此網站可以搜索代碼很方便)  C# (CSharp) Mono.Security.Cryptography MD2.ComputeHash Examples
【7】參考MSDN MD5官方文檔 MD5 類 代碼參考的 SHA256 類
【8】python3中digest()和hexdigest()區別
【9】 字符編碼之ASCII、UTF-8、UTF-16的區別


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM