我一直在想是否有可能验证这个大数字是这个星球上每张SIM卡的唯一代码,ICCID。
如果有,是否有人有代码检查它是否在T-SQL函数上有效?
我想在不需要数据库的任何编程语言的情况下完成它。
我在C#上找到了这个代码,但是我无法将其转换为SQL,因为我只是吮吸数学和c#而这个<<
运算符刚刚结束了我!
private bool IccidIsValid(string iccid)
{
try
{
int numberStringLength = 18;
int cs = 0;
int dodd;
for (int i = 0; i < numberStringLength; i += 2)
{
dodd = Convert.ToInt32(iccid.Substring(i + 1, 1)) << 1;
cs += Convert.ToInt32(iccid.Substring(i, 1)) + (int)(dodd / 10) + (dodd % 10);
}
cs = (10-(cs % 10)) % 10;
if (cs == Convert.ToInt32(iccid.Substring(numberStringLength, 1)))
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
return false;
}
}
答案 0 :(得分:1)
这个(Bitshift operations in T-SQL)堆栈溢出文章应该具有将c#的位移转换为TSQL所需的内容。您也可以使用SQL CLR功能来使用.NET代码(可能更高效),而不是将其转换为TSQL。
答案 1 :(得分:0)
我找到了它!
CREATE FUNCTION dbo.usp_ValidateICCID ( @inputString VARCHAR(20) )
RETURNS TINYINT
AS BEGIN
DECLARE @result TINYINT
IF @inputString NOT LIKE ('%[0-9]%[0-9]%[0-9]%')
RETURN 2
DECLARE @charTable TABLE (
Position INT NOT NULL,
ThisChar CHAR(1) NOT NULL,
Doubled TINYINT,
Summed TINYINT )
SET @inputString = CAST(@inputString AS CHAR(20))
INSERT INTO @charTable(Position, ThisChar)
SELECT 1, SUBSTRING(@inputString, 1, 1) UNION ALL
SELECT 2, SUBSTRING(@inputString, 2, 1) UNION ALL
SELECT 3, SUBSTRING(@inputString, 3, 1) UNION ALL
SELECT 4, SUBSTRING(@inputString, 4, 1) UNION ALL
SELECT 5, SUBSTRING(@inputString, 5, 1) UNION ALL
SELECT 6, SUBSTRING(@inputString, 6, 1) UNION ALL
SELECT 7, SUBSTRING(@inputString, 7, 1) UNION ALL
SELECT 8, SUBSTRING(@inputString, 8, 1) UNION ALL
SELECT 9, SUBSTRING(@inputString, 9, 1) UNION ALL
SELECT 10, SUBSTRING(@inputString, 10, 1) UNION ALL
SELECT 11, SUBSTRING(@inputString, 11, 1) UNION ALL
SELECT 12, SUBSTRING(@inputString, 12, 1) UNION ALL
SELECT 13, SUBSTRING(@inputString, 13, 1) UNION ALL
SELECT 14, SUBSTRING(@inputString, 14, 1) UNION ALL
SELECT 15, SUBSTRING(@inputString, 15, 1) UNION ALL
SELECT 16, SUBSTRING(@inputString, 16, 1) UNION ALL
SELECT 17, SUBSTRING(@inputString, 17, 1) UNION ALL
SELECT 18, SUBSTRING(@inputString, 18, 1) UNION ALL
SELECT 19, SUBSTRING(@inputString, 19, 1) UNION ALL
SELECT 20, SUBSTRING(@inputString, 20, 1)
DELETE FROM @charTable
WHERE ThisChar NOT LIKE('[0-9]')
DECLARE @tempTable TABLE (
NewPosition INT IDENTITY(1,1),
OldPosition INT )
INSERT INTO @tempTable (OldPosition)
SELECT Position
FROM @charTable
ORDER BY Position ASC
UPDATE @charTable
SET Position = t2.NewPosition
FROM @charTable t1
INNER JOIN @tempTable t2 ON t1.Position = t2.OldPosition
IF ( SELECT MAX(Position) % 2 FROM @charTable ) = 0
BEGIN
UPDATE @charTable
SET Doubled = CAST(ThisChar AS TINYINT) * 2
WHERE Position % 2 <> 0
END
ELSE BEGIN
UPDATE @charTable
SET Doubled = CAST(ThisChar AS TINYINT) * 2
WHERE Position % 2 = 0
END
UPDATE @charTable
SET Summed =
CASE WHEN Doubled IS NULL
THEN CAST(ThisChar AS TINYINT)
WHEN Doubled IS NOT NULL AND Doubled <= 9
THEN Doubled
WHEN Doubled IS NOT NULL AND Doubled >= 10
THEN (Doubled / 10) + (Doubled - 10)
END
IF ( SELECT SUM(Summed) % 10 FROM @charTable ) = 0
SET @result = 1
ELSE
SET @result = 0
RETURN @result
END
我只是重新制作了互联网版本,以便在不需要临时表的情况下加快速度:
alter function dbo.usp_ValidaICCID(@inputStr varchar(20))
RETURNS tinyint
as begin
declare @workStr varchar(20)
declare @strLength smallint
declare @i smallint
declare @sum smallint
declare @prod smallint
declare @digit char(1)
declare @evenInd tinyint
declare @result tinyint
if(@inputStr not LIKE ('%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]%[0-9]'))
return 2
set @strLength = len ( @inputStr )
set @i = 1
set @workStr = ''
WHILE @i <= @strLength
BEGIN
set @digit = SUBSTRING(@inputStr, @i, 1)
if(@digit LIKE '[0-9]') set @workStr = @workStr + @digit
set @i = @i +1
end
set @sum = 0
set @evenInd = 0
if(@strLength % 2 = 0)
set @evenInd = 1
set @i = 1
WHILE @i <= @strLength
BEGIN
set @digit = SUBSTRING(@workStr, @i, 1)
set @prod = CONVERT(smallint , @digit)
if(@evenInd = 1 and @i % 2 = 1 or @evenInd = 0 and @i % 2 = 0) set @prod = @prod * 2
if(@prod >= 10) set @prod = @prod/10 + @prod-10
set @sum = @sum + @prod
set @i = @i +1
END
if(@sum %10 = 0)
set @result = 1
else
set @result = 0
return @result
end