C# 用于跨进程/平台的字符串列表的一致哈希代码
我看了看下面的问题: 并问Jon Skeet以下问题: “@JonSkeet该解决方案是否能在多个AppDomain中产生与字符串列表一致的结果?我有一个WCF服务器,其中有来自不同平台(XP、Vista、Win7或不同的.Net Framework 3.5及更高版本)的多个应用程序可以连接,在所有这些情况下,我需要从字符串列表中获得一致的哈希代码,是这样吗?如果不是,我将如何实现?” 他的回答是: “@RandRandom:你不应该为此使用GetHashCode——这并不意味着在不同的进程之间保持一致。你应该使用类似SHA-256的东西。” 我不确定他的建议答案的实施情况如何,所以为了不在评论区提出详细问题,我决定创建一个新问题 因此,假设您有以下列表:C# 用于跨进程/平台的字符串列表的一致哈希代码,c#,C#,我看了看下面的问题: 并问Jon Skeet以下问题: “@JonSkeet该解决方案是否能在多个AppDomain中产生与字符串列表一致的结果?我有一个WCF服务器,其中有来自不同平台(XP、Vista、Win7或不同的.Net Framework 3.5及更高版本)的多个应用程序可以连接,在所有这些情况下,我需要从字符串列表中获得一致的哈希代码,是这样吗?如果不是,我将如何实现?” 他的回答是: “@RandRandom:你不应该为此使用GetHashCode——这并不意味着在不同的进程
var fooList = new List<string>()
{
"",
"StatAccount",
"Value",
"9900000701",
"P1",
"3",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"VFE-Lage.xlsx",
"",
"",
"False",
"",
"",
"",
"",
"",
"",
"",
"",
};
var-doulist=new List()
{
"",
“StatAccount”,
“价值”,
"9900000701",
“P1”,
"3",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
“VFE Lage.xlsx”,
"",
"",
“假”,
"",
"",
"",
"",
"",
"",
"",
"",
};
现在我需要一个比检查SequenceEquality更容易/更快的哈希代码,我的列表是不变的,它永远不会改变
我有一门课看起来像这样:
public class Foo
{
private List<string> _fooList = new List<string>();
private int _fooListHashCode;
public List<string> FooList
{
get
{
return _fooList;
}
set
{
_fooList = value;
_fooListHashCode = GetListsHashCode(value);
}
}
public static int GetListsHashCode(List<string> list)
{
//return hashCode...
return 0;
}
public override int GetHashCode()
{
return _fooListHashCode;
}
public override bool Equals(object obj)
{
var foo = obj as Foo;
if (foo == null)
return false;
return this._fooListHashCode == foo._fooListHashCode;
}
}
公共类Foo
{
私有列表_doulist=新列表();
私有整数码;
公之于众的傻瓜
{
得到
{
返回-傻瓜;
}
设置
{
_愚人=价值;
_DoublistHashCode=GetListsHashCode(值);
}
}
公共静态int GetListsHashCode(列表)
{
//返回哈希代码。。。
返回0;
}
公共覆盖int GetHashCode()
{
返回(u)hashcode ;;
}
公共覆盖布尔等于(对象对象对象)
{
var foo=对象作为foo;
if(foo==null)
返回false;
返回此值。_-foulisthashcode==foo。_-foulisthashcode;
}
}
这应该适用于使用SHA256哈希比较两个字符串列表
private bool CompareLists(IEnumerable<string> value1, IEnumerable<string> value2)
{
// First convert lists to single strings
var encoder = new UTF8Encoding();
var hash = new SHA256CryptoServiceProvider();
var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
foreach (var item in value1)
{
sb1.Append(item);
}
foreach (var item in value2)
{
sb2.Append(item);
}
// Then hash and compare
return Convert.ToBase64String(hash.ComputeHash(encoder.GetBytes(sb1.ToString()))) ==
Convert.ToBase64String(hash.ComputeHash(encoder.GetBytes(sb2.ToString())));
}
私有布尔比较列表(IEnumerable value1,IEnumerable value2)
{
//首先将列表转换为单个字符串
var编码器=新的UTF8Encoding();
var hash=新的SHA256CryptoServiceProvider();
var sb1=新的StringBuilder();
var sb2=新的StringBuilder();
foreach(value1中的var项目)
{
sb1.附加(项目);
}
foreach(value2中的var项目)
{
sb2.附加(项目);
}
//然后散列并比较
返回Convert.ToBase64String(hash.ComputeHash(encoder.GetBytes(sb1.ToString()))==
Convert.ToBase64String(hash.ComputeHash(encoder.GetBytes(sb2.ToString()));
}
由于您的主列表是不可变的,您可能需要为它计算一次哈希并存储它,这将使此方法的性能更高。也许有更好的办法,但这应该行得通
注意:要使此方法返回true,两个列表必须完全相同;相同数量的字符串,相同的字符串(包括大小写),顺序相同。根据我之前回答的注释:
private int GetHashCode(IEnumerable<string> value)
{
var encoder = new UTF8Encoding();
var hash = new SHA256CryptoServiceProvider();
var sb = new StringBuilder();
foreach (var item in value)
{
sb.Append(item);
}
return
Convert.ToInt32(
new Rfc2898DeriveBytes(sb.ToString(),
hash.ComputeHash(encoder.GetBytes(sb.ToString()))).GetBytes(4));
}
private int GetHashCode(IEnumerable值)
{
var编码器=新的UTF8Encoding();
var hash=新的SHA256CryptoServiceProvider();
var sb=新的StringBuilder();
foreach(价值中的var项目)
{
某人附加(项目);
}
返回
转换为32(
新的Rfc2898DeriveBytes(sb.ToString(),
ComputeHash(encoder.GetBytes(sb.ToString())).GetBytes(4));
}
如何将其转换为int以返回GetHashCode方法?因为我需要这些对象的哈希集和字典。在这种情况下,我根本不会使用哈希,我会使用Rfc2898DeriveBytes获得一个4字节的数组,您可以将其转换为int。我将发布第二个答案。