我在SQL Server 2008中有一个现有的数据库,它通过现有
PHP Web应用程序的存储过程执行用户身份验证. Web应用程序向存储过程发送一个字符串,但存储过程存储,并使用SQL Checksum(
http://msdn.microsoft.com/en-us/library/ms189788.aspx)检查该值.存储过程将字符串转换为NVARCHAR(50),并将CHECKSUM存储为用户表中的int.
我现在正在现有数据库上编写一个新的Java应用程序,我正在编写一个自定义的Spring身份验证管理器.我想在Java中重新实现CHECKSUM算法,所以我不需要调用存储过程来执行转换,但是我找不到有关SQL CHECKSUM如何工作的任何文档.
我尝试了下面的代码,猜测它是CRC32,但它无法返回与SQL CHECKSUM相同的值:
String pass = "foobar";
CRC32 crc32 = new CRC32();
crc32.update(pass.getBytes("UTF-16")); //This is due to the stored procedure casting as nvarchar
crc32.getValue();
任何人都可以向我指出SQL CHECKSUM使用的算法,所以我可以用Java重新实现它吗?
问题还在于哪种算法不能提供最佳的安全散列.安全性超出了此特定实例中的要求,因为我们不准备强制重置系统密码.问题是T-SQL CHECKSUM使用了什么算法,因此可以重新实现.这个特殊的用例是用于auth,但是在许多不同的应用中有可能需要这样做.
最佳答案 在SQL Server论坛上,在这个
page,它声明:
SQL Server中的内置CHECKUM函数基于一系列4位左旋转xor运算.有关更多说明,请参阅此post.
我能够将BINARY_CHECKSUM移植到c#(抱歉我手头没有Java编译器),它似乎正在工作……我稍后会看看普通的CHECKSUM ……
private int SQLBinaryChecksum(string text)
{
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;
}