0

我一直想知道是否有可能验证这个大数字,它是地球上每张 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;
    }
}
4

2 回答 2

1

这篇(T-SQL 中的位移位操作)堆栈溢出文章应该包含将位移位从 c# 转换为 TSQL 所需的内容。您也可以使用 SQL CLR 功能来使用您的 .NET 代码(可能性能更高),而不是将其转换为 TSQL。

于 2014-12-31T18:45:17.670 回答
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    
于 2015-01-02T20:16:09.613 回答