使用 text/varchar/image 数据,调用 SELECT BINARY_CHECKSUM('abcdefghijklmnop'), dbo.fnPesoBinaryChecksum('abcdefghijklmnop')
整数数据,调用SELECT BINARY_CHECKSUM(123),dbo.fnPesoBinaryChecksum(CAST(123 AS VARBINARY))
我还没有弄清楚如何计算大于 255 的整数的校验和。
CREATE FUNCTION dbo.fnPesoBinaryChecksum
(
@Data IMAGE
)
RETURNS INT
AS
BEGIN
DECLARE @Index INT,
@MaxIndex INT,
@SUM BIGINT,
@Overflow TINYINT
SELECT @Index = 1,
@MaxIndex = DATALENGTH(@Data),
@SUM = 0
WHILE @Index <= @MaxIndex
SELECT @SUM = (16 * @SUM) ^ SUBSTRING(@Data, @Index, 1),
@Overflow = @SUM / 4294967296,
@SUM = @SUM - @Overflow * 4294967296,
@SUM = @SUM ^ @Overflow,
@Index = @Index + 1
IF @SUM > 2147483647
SET @SUM = @SUM - 4294967296
ELSE IF @SUM BETWEEN 32768 AND 65535
SET @SUM = @SUM - 65536
ELSE IF @SUM BETWEEN 128 AND 255
SET @SUM = @SUM - 256
RETURN @SUM
END
其实这是对 MS 功能的改进,因为它接受 TEXT 和 IMAGE 数据。
CREATE FUNCTION [dbo].[fnPesoTextChecksum]
(
@Data TEXT
)
RETURNS INT
AS
BEGIN
DECLARE @Index INT,
@MaxIndex INT,
@SUM BIGINT,
@Overflow TINYINT
SELECT @Index = 1,
@MaxIndex = DATALENGTH(@Data),
@SUM = 0
WHILE @Index <= @MaxIndex
SELECT @SUM = (16 * @SUM) ^ ASCII(SUBSTRING(@Data, @Index, 1)),
@Overflow = @SUM / 4294967296,
@SUM = @SUM - @Overflow * 4294967296,
@SUM = @SUM ^ @Overflow,
@Index = @Index + 1
IF @SUM > 2147483647
SET @SUM = @SUM - 4294967296
ELSE IF @SUM BETWEEN 32768 AND 65535
SET @SUM = @SUM - 65536
ELSE IF @SUM BETWEEN 128 AND 255
SET @SUM = @SUM - 256
RETURN @SUM
END