Skip to content

Instantly share code, notes, and snippets.

@angoca
Created June 16, 2020 03:21
Show Gist options
  • Save angoca/34529881dd135849e6522e08007cd5ad to your computer and use it in GitHub Desktop.
Save angoca/34529881dd135849e6522e08007cd5ad to your computer and use it in GitHub Desktop.
PCI for Db2 database
--#SET TERMINATOR @
BEGIN
DECLARE VALID SMALLINT;
DECLARE VAL SMALLINT;
DECLARE PROCEDURE LUHN_TEST (
IN NUMBER VARCHAR(24),
OUT RET SMALLINT
)
BEGIN
DECLARE TYPE CARD_NUMBER AS VARCHAR(1) ARRAY [24];
DECLARE LENGTH SMALLINT;
DECLARE REVERSE CARD_NUMBER;
DECLARE I SMALLINT;
DECLARE POS SMALLINT;
DECLARE S1 SMALLINT;
DECLARE S2 SMALLINT;
DECLARE TEMP SMALLINT;
DECLARE INVALID_CHAR CONDITION FOR SQLSTATE 'LUHN1';
SET RET = 1;
-- Reverse the order of the digits in the number.
SET LENGTH = LENGTH(NUMBER);
SET I = 1;
WHILE (I <= LENGTH) DO
SET POS = LENGTH - I + 1;
SET REVERSE[POS] = SUBSTR(NUMBER, I, 1);
IF (ASCII(REVERSE[POS]) < 48 OR 57 < ASCII(REVERSE[POS])) THEN
SIGNAL INVALID_CHAR SET MESSAGE_TEXT = 'Invalid character, not a digit';
END IF;
SET I = I + 1;
END WHILE;
-- Take the first, third, ... and every other odd digit in the reversed digits and sum them to form the partial sum s1.
SET S1 = 0;
SET I = 1;
WHILE (I <= LENGTH) DO
IF (MOD(I, 2) = 1) THEN
SET S1 = S1 + REVERSE[I];
END IF;
-- TODO Convertir a log4db2 pero con comentario.
-- CALL DBMS_OUTPUT.PUT_LINE('I ' || I || ', S1 ' || S1 || ', val ' || REVERSE[I]);
SET I = I + 1;
END WHILE;
-- Taking the second, fourth ... and every other even digit in the reversed digits.
SET S2 = 0;
SET TEMP = 0;
SET I = 1;
WHILE (I <= LENGTH) DO
IF (MOD(I, 2) = 0) THEN
-- Multiply each digit by two and sum the digits if the answer is greater than nine to form partial sums for the even digits.
SET TEMP = REVERSE[I] * 2;
IF (TEMP > 9) THEN
SET TEMP = (TEMP / 10) + (MOD(TEMP, 10));
END IF;
-- Sum the partial sums of the even digits to form s2.
SET S2 = S2 + TEMP;
END IF;
-- TODO Convertir a log4db2 pero con comentario.
-- CALL DBMS_OUTPUT.PUT_LINE('I ' || I || ', S2 ' || S2 || ', TEMP ' || TEMP || ' val ' || REVERSE[I]);
SET I = I + 1;
END WHILE;
-- If s1 + s2 ends in zero then the original number is in the form of a valid credit card number as verified by the Luhn test.
SET RET = 0;
SET TEMP = S1 + S2;
IF (MOD(TEMP, 10) = 0) THEN
SET RET = 1;
-- TODO Convertir a log4db2 pero con comentario.
CALL DBMS_OUTPUT.PUT_LINE('It is a valid number ' || S1 || '+' || S2 || '=' || TEMP);
ELSE
-- TODO Convertir a log4db2 pero con comentario.
CALL DBMS_OUTPUT.PUT_LINE('It is NOT a valid number ' || S1 || '+' || S2 || '=' || TEMP);
END IF;
END;
BEGIN
-- TODO Generar una tabla temporal para un resumen del reporte.
-- TODO Generar una tabla temporal para la informacion del reporte detallado.
-- TODO Definir una variable que indique el porcentaje de registros para el muestreo de datos (ver como se hace un query muestreo)
-- TODO Definir una variable que indique el porcentaje por el que se define una columna como contenedora de tarjetas.
-- TODO Recorrer todos los esquemas que no comiencen con SYS%, sobre la tabla syscat.tables
-- TODO Recorrer todas las tablas que sean normales (no MQT, ni vistas, ni federadas) sobre la tabla syscat.tables
-- TODO Recorrer todas las columnas de una tabla dada
-- TODO De las columnas, solo tomar las numericas de mas de 16 digitos, o las de caracter de mas de 16 digitos.
-- Se hace la suposicion que el campo solo puede contener una tarjeta en su totalidad, no como parte del campo.
-- TODO Generar un query sobre la columna dada extrayendo el campo de cada registro. Tener en cuenta el tamano de la muestra)
-- TODO Hacer validacion de los datos, que no sea nulo, que tenga 16 digitos, se le puede hacer un trim si es cadena.
-- TODO Ejecutar el algoritmo de Luhn para validar si es posible que sea una tarjeta de credito valida.
SET VAL = 1234;
CALL LUHN_TEST(VAL, VALID);
-- TODO insertar en el informe, nombre de esquema, nombre de tabla, nombre de columna, la cantidad de registros del tamano de la muestra analizada, la cantidad de registros que tuvieron un lunh satisfactorio.
-- TODO Generar reporte de indicando cuantos esquemas, tablas y columnas se procesaron. Cuantas columnas tuvieron un luhn positivo superior a un valor.
END;
END
@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment