【问题标题】:How do I use SqlFunctions.Checksum in C# to generate hashed string如何在 C# 中使用 SqlFunctions.Checksum 生成散列字符串
【发布时间】:2018-12-18 17:42:46
【问题描述】:

我正在寻找 C# 中 CHECKSUM MS SQL 函数的副本。 当我在 IDataReader 中获取数据时,我想使用 SqlFunctions.Checksum 方法将一列从普通字符串转换为哈希字符串。

示例代码:

IDataReader reader = base.DataBase.ExecuteReader(cmd);
var dsList = new List<IHumanReadableData>();
dsList = _humanReadableDataObjectMapper.MapList(reader);

dsList.ForEach(r => { 
         r.PersonName = SqlFunctions.Checksum(r.PersonName).ToString(); 
                    });

这个 sn-p 得到一个错误:“这个函数只能从 LINQ to Entities 调用”。

注意:

  • 我不想使用标准哈希算法,因为我不想太长 要生成的哈希字符串。

  • 我想要一个散列但相对较小的字符串,以便我的用户可以 在不暴露敏感数据的情况下比较它们(即 人名)。

  • 我不想使用 CHECKSUM 从 MS SQL 执行此操作 功能。

有什么想法吗??

【问题讨论】:

    标签: c# asp.net sql-server


    【解决方案1】:

    调用.ForEach() 方法会出现此错误。这是Linq-To-Object 的方法。但是SqlFunctionsLinq-To-Entities 方法。所以你有这个错误。

    您可以做的是创建一个扩展方法计算哈希,如 T-SQL 的CheckSum(请参阅此处C# implementation of CheckSum())并在您的 C# 代码中使用它。让我举个例子:

    首先,为string类型创建一个扩展方法:

    public static class Extension
    {
        public static int Checksum(this string text)
        {
            if (text == null)
                return 0;
    
            long sum = 0;
            byte overflow;            
            for (int i = 0; i < text.Length; i++)
            {
                sum = (long)((16 * sum) ^ Convert.ToUInt32(text[i]));
                overflow = (byte)(sum / 4294967296);
                sum = sum - overflow * 4294967296;
                sum = sum ^ overflow;
            }
    
            if (sum > 2147483647)
                sum = sum - 4294967296;
            else if (sum >= 32768 && sum <= 65535)
                sum = sum - 65536;
            else if (sum >= 128 && sum <= 255)
                sum = sum - 256;
    
            return (int)sum;
        }
    }
    

    并在你的方法中使用它:

    static void Main(string[] args)
    {
        List<Person> persons = new List<Person>()
        {
            new Person(){IdPerson = 1, FirstName = "1" },
            new Person(){IdPerson = 2, FirstName = "2" },
            new Person(){IdPerson = 3, FirstName = "3" },
            new Person(){IdPerson = 4},
        };
    
        persons.ForEach(r => {
            r.FirstName = r.FirstName.Checksum().ToString();
        });
    }
    

    更新:

    MSDN does not say what algorithm is used in CHECKSUM function。所以你必须使用LINQ-to-Entities 才能使用T-SQL 函数。

    【讨论】:

    • 我浏览了提供的链接,但它没有解释 SqlFunctions.Checksum 实现。它已经解释了如何使用 BINARY_CHECKSUM 创建散列,但我不确定它有多可靠,因为我尝试使用 BINARY_CHECKSUM 函数在 MSSQL 中散列一个字符串,以及我使用链接中提供的代码在 c# 中散列的相同字符串。输出完全不同。
    猜你喜欢
    • 2018-12-30
    • 2022-01-18
    • 2017-04-10
    • 2022-11-24
    • 2014-09-09
    • 2020-07-14
    • 2011-02-01
    • 2014-05-01
    • 1970-01-01
    相关资源
    最近更新 更多