日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

用.NET写“算命”程序

發(fā)布時間:2023/12/4 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用.NET写“算命”程序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

“算命”,是一種迷信,我父親那一輩卻執(zhí)迷不悟,有時深陷其中,有時為求一“上上簽”,甚至不惜重金,向“天神”保佑。我曾看到過有些算命網(wǎng)站,可以根據(jù)人的生辰八字,來求得這個人一生的財運、桃花運,如果第一卦算得不好,還可以向“天神”“請愿”(充錢),再算一卦,直到達到好運為止。

作為一個深信唯物辯證法的人來說,這些東西當然是不信。

但仔細琢磨,發(fā)現(xiàn)這些東西其中需要有些科學道理。我可以將算命總結(jié)為以下“三要素”:

  • 一致性? ?

    “命中注定”,因此“算”出來的東西,不管早算還是晚算,什么時候算,結(jié)果應該都一樣。

  • 無規(guī)律性

    “天機不可泄露”,因此輸入相近的姓名等參數(shù),輸出應該相差較遠。“每個人的命運各不相同”,比如狗二和狗三,相差只有一個字,但他們的命運并不一定會幾乎一樣。算法應該也考慮這一點。

  • 個性化

    輸入?yún)?shù)應該盡量個性化,不要像十二生肖/十二星座那樣,和性別做排列組合,只有12x2=24種結(jié)果。否則撞車的人太多,容易露餡?。因此輸入?yún)?shù)必須個性化,最好是姓名、性別再加上生辰八字(出生時間)。

  • 可操作性

    孜孜不倦的求卦者,可能會“誠心誠意”想求個“上上簽”,因此在一致性的基礎上,必須要加一點點“可操作性”。這個可以當作一個單獨的輸入?yún)?shù)來表示。

  • 如果將算命當作一個函數(shù),那它的輸入無疑是姓名、其它個人信息和誠心,輸出就是一個分數(shù)(0-100),可以用下圖的代碼表示:

    int destinyScore = f(name, otherPersonalInformation, faith);

    下面,我將用.NET實現(xiàn)這個功能。

    最簡單的“算命”程序

    最初想法

    如果只以姓名作為輸入,那么這個函數(shù)可以簡化為:

    int destinyScore = f(name);

    這可能就好辦多了,如.NET中的.GetHashCode(),即可快速獲取一個字符串的哈希值,這個哈希值應該是固定的(嗎?),該值的取值范圍是int.MinValue-int.MaxValue。因此最簡單的辦法,可以先可以通過對100求模,此時的取值范圍是-99~99;然后再取絕對值+1即可,代碼如下:

    int GetForturn(string name) { return Math.Abs(name.GetHashCode() % 100) + 1; }

    在.NET?Framework?4.8中運行,可以算出我(周杰)的得分固定為15分。

    最簡單算法的缺點-.NET?Core的不一致

    在.NET?Core中,這個算法每次重新運行,算出的結(jié)果都不同,因為.NET?Core為了確保安全性,在應用程序啟動時,會隨機生成一個字符串哈希值種子,因此每次exe運行,哈希值都會變,文檔是這么說的:

    哈希代碼本身不一定是穩(wěn)定的。?對于單個版本的 .NET, 相同字符串的哈希代碼可能跨 .net 實現(xiàn)、跨 .NET 版本和跨 .NET 平臺?(如32位和64位)?不同。?在某些情況下, 它們甚至不同于應用程序域。?這意味著, 同一程序的兩次后續(xù)運行可能返回不同的哈希代碼。(源自:https://docs.microsoft.com/zh-cn/dotnet/api/system.string.gethashcode?view=netframework-4.8 )

    很顯然,這不符合“一致性”,看來想簡單地通過GetHashCode()快速“算命”的想法落空了,只能使用標準的哈希算法。

    當然,使用如此簡單的算法,客戶知道了,可能也不太情愿消費更多的“誠意金”了。

    哈希算法

    哈希算法可以給任意長度的字符轉(zhuǎn)換為一串二進制數(shù)組,也就是哈希值。.NET內(nèi)置了許多不同的哈希算法可供選擇:

    1.?有單純的哈希,如MD5、SHA1之類;

    2.?有“加鹽”的哈希,如HMACSHA、HMACSHA256等;

    3.?有可指定生成長度、可多次迭代、綜合性“加鹽”的哈希,如Rfc2898DeriveBytes。

    我們要指定一點點“天機”(加鹽),但“天機不可泄露”,因此簡單地MD5等單純哈希算法排除;

    我們要轉(zhuǎn)化為一個整數(shù),最大的整數(shù)類型,long/Int64,為64位,而最小的內(nèi)置哈希算法,MD5,就已達128位。因此也要排除HMACSHA等“加鹽”哈希。當然這些哈希值也可以手動截取部分長度,但安全性是個問號(也受強迫癥影響)。

    搞過ASP.NET?Identity登錄的都知道里面用到了Rfc2898DeriveBytes,它默認為ASP.NET?Core做了10000次迭代,用多次迭代的方式(而不是引入一個新哈希算法的方式),確保了安全性。搞對稱加密的時候,有時也用這個類將客戶的密碼轉(zhuǎn)換為加密算法的密鑰(key),非常有用。

    所以最終我們選擇了Rfc2898DeriveBytes,該算法可以生成任意指定長度的哈希值。這個類的構造函數(shù)要求輸入一個鹽值和迭代次數(shù),在這個示例中我們?nèi)∫粋€別人不知道的值(代碼中寫死了,你們假裝不知道,你們想用這個代碼時可以改改?)。可以寫出如下代碼:

    int GetForturn(string name) { using (var h = new Rfc2898DeriveBytes(name, salt: new byte[8] { 44, 2, 3, 4, 5, 6, 7, 8}, iterations: 10086)) { return (int)(BitConverter.ToUInt64(h.GetBytes(8), 0) % 100) + 1; }; }

    我從網(wǎng)上自動生成了888個姓名,然后調(diào)用該函數(shù),發(fā)現(xiàn)得分超過90分“上上簽”標準的,只有83個,相同于十分之一,符合分布特點(詳情見Github上的代碼)。可見算出一卦80分以上的“上簽”,已經(jīng)非常不容易了。

    通過以下代碼,可以算出“狗二”是48分,“狗三”是96分,可見一字之差相差甚遠:

    GetForturn("狗二").Dump(); // 48 GetForturn("狗三").Dump(); // 96

    完整算法

    最后,依葫蘆畫瓢,加上個人信息參數(shù)(生日)和“誠意金次數(shù)”,完成最后的算法:

    int GetForturn(string name, DateTime birthDay, int faithCount) { using (var h = new Rfc2898DeriveBytes(name + birthDay + faithCount, salt: new byte[8] { 44, 2, 3, 4, 5, 6, 7, 8 }, iterations: 10086)) { return (int)(BitConverter.ToUInt64(h.GetBytes(8), 0) % 100) + 1; }; }

    然后又是“狗二”和“狗三”,加上他們的生日參數(shù)后,默認他們的得分是95分和3分:

    GetForturn("狗二", new DateTime(1994, 5, 17), 0).Dump(); // 95 GetForturn("狗三", new DateTime(1996, 11, 3), 0).Dump(); // 3

    但狗三經(jīng)過1次“誠意金”后,也求得了高達99分以上的“上上簽”:

    GetForturn("狗二", new DateTime(1994, 5, 17), 0).Dump(); // 98 GetForturn("狗三", new DateTime(1996, 11, 3), ).Dump(); // 99

    最后的話

    Rfc2898DeriveBytes非常有用,本文說了Rfc2898DeriveBytes的一種使用場景,相信各位在工作當時也經(jīng)常會有機會去接觸它。

    我將上述功能做了一個頁面,愿博君一笑:https://destiny.starworks.cc/

    出處:微信公眾號【DotNet騷操作】微信可能無法留言,可點擊“閱讀原文”轉(zhuǎn)到博客園留言。原文鏈接:https://www.cnblogs.com/sdflysha/p/20190905-fortune-with-dotnet.html

    覺得好看,請點這里↓↓↓

    總結(jié)

    以上是生活随笔為你收集整理的用.NET写“算命”程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。