我需要生成一个资源域前缀基于给定的路径和配置的资源域的数量在一个确定的方式,良好的分布。例如,如果传递路径“/script/site.js”,则返回“res”,其中“”是介于0和配置的资源域数量之间的整数。
使用C 3.0。
到目前为止:
var resourceDomainCount = 4;
var hasher = System.Security.Cryptography.SHA1.Create();
var paths = new [] {
"/App_Themes.0.1.433.232/images/buttonsBackgrounds.jpg",
"/App_Themes.0.1.433.232/images/blahblah.jpg",
"/App_Themes.0.1.433.232/images/pagebg.gif",
"/App_Themes.0.1.433.232/site.css",
"/script/site.js",
"/App_Themes.0.1.433.232/images/different.jpg",
"/App_Themes.0.1.433.232/images/shadows.jpg",
"/Handlers/ImageHandler.ashx?type=l&id=123&s=g&index=0",
"/Handlers/ImageHandler.ashx?type=l&id=234&s=g&index=0",
"/Handlers/ImageHandler.ashx?type=l&id=345&s=g&index=0",
"/Handlers/ImageHandler.ashx?type=p&id=MyProduct&s=g&index=0",
"/Handlers/ImageHandler.ashx?type=p&id=WineGreat&s=g&index=0",
"/Handlers/ImageHandler.ashx?type=p&id=YayYay&s=g&index=0"
};
foreach (var path in paths) {
var pathHash = hasher.ComputeHash(Encoding.ASCII.GetBytes(path));
var singleByteHash = pathHash.Aggregate(0, (a, b) => a ^ b);
var random = new Random((int)singleByteHash);
var resourceDomainIndex = random.Next(0, resourceDomainCount);
(resourceDomainIndex + ": " + path).Dump();
}
产生以下结果:
3:/app_themes.0.1.433.232/images/button背景.jpg
0:/应用程序主题0.1.433.232/images/blahblah.jpg
1:/app_themes.0.1.433.232/images/pagebg.gif
1:/app_themes.0.1.433.232/site.css
3:/script/site.js
1:/app_themes.0.1.433.232/images/different.jpg
3:/app_themes.0.1.433.232/images/shadows.jpg
1:/handlers/imagehandler.ashx?类型=L&ID=123&S=G&index=0
1:/handlers/imagehandler.ashx?类型=L&ID=234&S=G&index=0
0:/handlers/imagehandler.ashx?类型=L&ID=345&S=G&index=0
2:/handlers/imagehandler.ashx?类型=P&ID=MyProduct&S=G&Index=0
1:/handlers/imagehandler.ashx?类型=P&ID=WineGreat&S=G&Index=0
0:/handlers/imagehandler.ashx?类型=P&ID=YayAy&S=G&Index=0
没有得到我想要的发行版(那里只有一个'2'实例)。
有数以千计的输入字符串会一直更改,路径将在运行时生成,例如:
<a href="<%= GetPath("/script/site.js") %>">Link</a>
最佳答案
这比散列字符串简单得多(好吧,估计它已经是散列了),而且似乎得到了更好的分布:
Math.Abs(path.GetHashCode()) % resourceDomainCount