C# 用于跨进程/平台的字符串列表的一致哈希代码

C# 用于跨进程/平台的字符串列表的一致哈希代码,c#,C#,我看了看下面的问题: 并问Jon Skeet以下问题: “@JonSkeet该解决方案是否能在多个AppDomain中产生与字符串列表一致的结果?我有一个WCF服务器,其中有来自不同平台(XP、Vista、Win7或不同的.Net Framework 3.5及更高版本)的多个应用程序可以连接,在所有这些情况下,我需要从字符串列表中获得一致的哈希代码,是这样吗?如果不是,我将如何实现?” 他的回答是: “@RandRandom:你不应该为此使用GetHashCode——这并不意味着在不同的进程

我看了看下面的问题:

并问Jon Skeet以下问题:

“@JonSkeet该解决方案是否能在多个AppDomain中产生与字符串列表一致的结果?我有一个WCF服务器,其中有来自不同平台(XP、Vista、Win7或不同的.Net Framework 3.5及更高版本)的多个应用程序可以连接,在所有这些情况下,我需要从字符串列表中获得一致的哈希代码,是这样吗?如果不是,我将如何实现?”

他的回答是: “@RandRandom:你不应该为此使用GetHashCode——这并不意味着在不同的进程之间保持一致。你应该使用类似SHA-256的东西。”

我不确定他的建议答案的实施情况如何,所以为了不在评论区提出详细问题,我决定创建一个新问题

因此,假设您有以下列表:

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。我将发布第二个答案。