Web uygulamaları içerisinde customvalidator yardımı ile yapılabilmekte olan bu durum SQL Server tarafında nasıl yapılabileceği konusunu bu yazıda size anlatıyor olacağım. Öncelikli olarak LHUN algoritmasının yapısını inceleyelim.
Lhun algoritması basit olarak kredi kartı gibi sayısal ifadelerin doğruluğunu kontrol etmek amacıyla kullanılan bir matematik algoritmasıdır. Bu algoritmaya “mod 10 algoritması” da denmektedir. Basit olarak bir dizi matematiksel işlem ile, verinin uygun bir kredi kartı numarası olup olmadığı tespit edilir. Eğer kredi kartı numarası uygun ise, sıradaki diğer işlemlere geçilebilir.
** Lhun algoritması sadece girilen sayısal ifadenin uygun bir kredi kartı numarası olup olmadığını belirten bir model sunar. İstemci tarafından girilen kredi kartı numarasının doğru olması sadece numaranın dünya çapında kabul görmüş bir algoritma ile doğrulanabildiğini gösterir. Oysaki, girilen kredi kartı numarasının geçerlilik süresinin, kart sahibinin isminin ve CVV2 gibi diğer kriterlerin kontrolüde gerekir ki bu tamamen ayrı bir süreçtir.
Kısaca Lhun algoritması şu şekilde çalışır.
1 – İlk olarak kredi kartı numarasının en sağ ikinci dijitinden başlanarak sırasıyla sola doğru ilerlenir. (Koduyazılırken soldan ikinci dijitten başlayıp ikişer ikişer de atlayabiliriz. ) İkişer ikişer atlanırken her bir dijitin iki katı hesap edilir. Elde edilen sonuçlardan değeri 10 ve 10′ dan büyük olanlar var ise bunların basamakları toplanır ve diğer 10′ dan küçük olan değerler eklenerek bir toplam değeri elde edilir.
2 – Daha sonra, iki katı alınan dijitlerin dışında kalan dijitler ele alınır ve bu dijitler bir birleriyle toplanarak bir toplam değeri daha elde edilir.
3 – Son olarak 1nci ve 2nci işlemlerdeki toplamların toplamı alınır ve sonucun 10 ile bölünüp bölünmediğine (bir başka deyişle mod 10′ un sıfır olup olmadığına) bakılır. Eğer 10 ile tam bölünebiliyorsa bu sayı dizisi bir kredi kartı numarasıdır. Olayı daha iyi anlamak için örnek bir 16 haneli sayı dizisini ele alalım.
Resim-1
Burada 5578 2920 6032 2610 sayı dizisinin geçerli bir kredi kartı numarası olup olmadığının Lhun algoritmasına göre nasıl tespit edilebildiğini görmektesiniz. Dikkat ederseniz sonuç 10 ile tam olarak bölünemediğinden sayı dizisi geçerli bir kredi kartı numarasını temsil etmemektedir. Sahip olduğunuz kredi kartları üzerinde yukarıdaki algoritmayı deneyebilir ve sonuçlarını inceleyebilirsiniz.
Şunuda belirtmekte fayda vardır ki, dünya çapında kullanılan çeşitli tipte kredi kartları mevcuttur. Örneğin master card, visa gibi. Bunlarında kendilerine has bir takım sayı dizisi kuralları vardır. Örneğin bir master card’ a ait kredi kartı numarasının ilk iki hanesi, 55 yada 50 olmak zorundadır. Bu, kartın bir master card olduğunun işaretidir.
Şimdi gelelim kullanacağımız function create etme işlemine bunun için aşağıdaki kod parçasını kullanacağız.
USE DBA
GO
CREATE FUNCTION dbo.usp_LuhnsAlgorithm (@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 — odds
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
Yazmış olduğumuz SQL function kullanımı ise aşağıdaki gibidir.
SELECT ‘5578292060322610’ [String],[dbo].[usp_LuhnsAlgorithm](‘5578292060322610’) [Valid Card?]
Resim-2
Valid Card için gelebilecek değerler 0,1 ve 2’dir. Bu değerlerin karşılıkları ise ;
0 à Geçerli bir numara değildir.
1 à Geçerli bir numaradır.
2à Belirsiz bir değerdir.
Resim-3
Konuyu bitirirken bir örnek daha vererek bitirmek istiyorum.
SELECT
‘371449635398431’ [Test String],
[dbo].[usp_LuhnsAlgorithm](‘371449635398431’) [Valid Card?]
UNION ALL
SELECT
‘3714 4963 5398 431’ [Test String],
[dbo].[usp_LuhnsAlgorithm](‘3714 4963 5398 431’) [Valid Card?]
UNION ALL
SELECT
’37XX XXXX 5398431′ [Test String],
[dbo].[usp_LuhnsAlgorithm](’37XX XXXX 5398431′) [Valid Card?]
UNION ALL
SELECT
‘Geçerli bir değer girmiyorum =)’ [Test String],
[dbo].[usp_LuhnsAlgorithm]( ‘Geçerli bir değer girmiyorum =)’) [Valid Card?]
UNION ALL
SELECT
‘1234123412341234’ [Test String],
[dbo].[usp_LuhnsAlgorithm](‘1234123412341234’) [Valid Card?]
UNION ALL
SELECT
‘5578292060322610’ [String],
[dbo].[usp_LuhnsAlgorithm](‘5578292060322610’) [Valid Card?]
Bu konuyla ilgili sorularınızı alt kısımda bulunan yorumlar alanını kullanarak sorabilirsiniz.
Referanslar