Crearemos una funcion llamada fnEncriptar que recibirá 2 parametros de tipo nvarchar: @entrada nvarchar(MAX) y @clave(25). Para este ejemplo usaré las misma frase (entrada) y clave usados en el artículo de wikipedia.
El primer paso es suprimir los espacios en blanco y opcionalmente pasamos la frase y clave a mayusculas.
SELECT @entrada = REPLACE(@entrada,' ','') SET @entrada = UPPER(@entrada) SELECT @clave = REPLACE(@clave,' ','') SET @clave=UPPER(@clave)
Seguidamente generamos los poligramas aplicando las reglas y los almacenamos en una variable de tabla.
DECLARE @poligrama TABLE(Idp INT IDENTITY(1,1), par NVARCHAR(2) NOT NULL) DECLARE @tam int,@pos INT SET @tam=LEN(@entrada) SET @pos=1 WHILE @pos<=@tam BEGIN IF (@pos+1)>@tam INSERT INTO @poligrama(par)VALUES(SUBSTRING (@entrada,@pos,1)+'X') ELSE IF SUBSTRING (@entrada,@pos,1)=SUBSTRING (@entrada,@pos+1,1) INSERT INTO @poligrama(par)VALUES(SUBSTRING (@entrada,@pos,1)+'X') ELSE INSERT INTO @poligrama(par)VALUES(SUBSTRING (@entrada,@pos,2)) SET @pos=@pos+2 END
A esta altura si hacemos un SELECT a la tabla poligramas tendremos el siguiente resultado:
Ahora procederemos aplicamos la regla a la contraseña eliminaremos los caracteres repetidos.
DECLARE @claveReducida NVARCHAR(25) SET @tam=LEN(@clave) SET @pos=1 SET @claveReducida='' WHILE @pos<=@tam BEGIN IF CHARINDEX(SUBSTRING(@clave,@pos,1),@claveReducida)=0 SET @claveReducida=@claveReducida+SUBSTRING(@clave,@pos,1) SET @pos = @pos +1 ENDEl siguiente paso es crear la matriz de encriptación (de intercambio) de caracteres.
N | O | R | I | A |
B | C | D | E | F |
G | H | K | L | M |
P | Q | S | T | U |
V | W | X | Y | Z |
Los primeros elementos de la matriz deben ser los caracteres de la clave:
DECLARE @Matriz TABLE (FILA TINYINT, COLUMNA TINYINT, LETRA NVARCHAR(1)) DECLARE @fmz TINYINT, @cmz TINYINT SET @pos = 1 SET @tam = LEN(@claveReducida) SET @fmz=1 WHILE @fmz<=5 AND @pos<=@tam BEGIN SET @cmz=1 WHILE @cmz<=5 AND @pos<=@tam BEGIN INSERT INTO @Matriz(FILA, COLUMNA, LETRA) VALUES(@fmz,@cmz,SUBSTRING(@claveReducida,@pos,1)) SET @pos = @pos + 1 SET @cmz= @cmz + 1 END SET @fmz= @fmz + 1 END
Debe completarse la fila inconclusa con caracteres del alfabeto que no esten en la clave.
--GENERAR EL ALFABETO
DECLARE @iL tinyint, @MaxiL tinyint --MAYUSCULAS SET @iL = 65 SET @MaxiL = 90 --minusculas --SET @iL = 97 --SET @MaxiL = 122 WHILE @cmz<=5 BEGIN WHILE @iL <= @MaxiL AND @cmz<=5 BEGIN IF CHAR(@iL) <> 'J' AND NOT EXISTS(SELECT * FROM @Matriz m WHERE m.LETRA = CHAR(@iL)) BEGIN INSERT INTO @Matriz(FILA, COLUMNA, LETRA) VALUES(@fmz,@cmz,CHAR(@iL)) -- SET @cmz= @cmz + 1 END SET @iL = @iL + 1 END END
Una vez hecho esto se completa la matriz al igual que el caso anterior excluyendo las J
WHILE @fmz<=5 AND (@iL<=@MaxiL) BEGIN SET @cmz=1 WHILE @cmz<=5 AND (@iL<=@MaxiL) BEGIN IF CHAR(@iL) <> 'J' AND NOT EXISTS(SELECT * FROM @Matriz m WHERE m.LETRA = CHAR(@iL)) BEGIN INSERT INTO @Matriz(FILA, COLUMNA, LETRA) VALUES(@fmz,@cmz,CHAR(@iL)) -- SET @cmz= @cmz + 1 END -- SET @iL = @iL + 1 END SET @fmz= @fmz + 1 END
Acá muestro parcialmente el resultado del segmento anterior
Ahora que se ha construido la matriz procedemos al intercambio de caracteres aplicando las reglas:
DECLARE @pgCount INT,@pgRow INT, @fila1 TINYINT, @fila2 TINYINT, @columna1 TINYINT, @columna2 TINYINT, @temp TINYINT DECLARE @car1 NVARCHAR(1), @car2 NVARCHAR(1),@ncar1 NVARCHAR(1),@ncar2 NVARCHAR(1) SELECT @pgCount = COUNT(*) FROM @poligrama p SET @pgRow = 1 SET @SalidaEncriptada = '' WHILE @pgRow <= @pgCount BEGIN --obtener los caracteres SELECT @car1 = SUBSTRING(p.par,1,1),@car2=SUBSTRING(p.par,2,1) FROM @poligrama p WHERE p.Idp = @pgRow --sustituir j por i if @car1 = 'J' SET @car1 = 'I' if @car2 = 'J' SET @car2 = 'I' --obtener la posicion de los caracteres en la matriz SELECT @fila1=m.FILA, @columna1 = m.COLUMNA FROM @Matriz m WHERE m.LETRA = @car1; SELECT @fila2=m.FILA, @columna2 = m.COLUMNA FROM @Matriz m WHERE m.LETRA = @car2; --APLICAR REGLAS IF @fila1=@fila2 --misma fila BEGIN IF @columna1<5 BEGIN SET @columna1 = @columna1 +1 END ELSE BEGIN SET @columna1 = 1 END -- IF @columna2<5 BEGIN SET @columna2 = @columna2 +1 END ELSE BEGIN SET @columna2 = 1 END END ELSE BEGIN IF @columna1=@columna2 -- misma columna BEGIN IF @fila1<5 BEGIN SET @fila1 = @fila1 +1 END ELSE BEGIN SET @fila1 = 1 END -- IF @fila2<5 BEGIN SET @fila2 = @fila2 +1 END ELSE BEGIN SET @fila2 = 1 END END ELSE BEGIN SET @temp = @columna1 SET @columna1 = @columna2 SET @columna2 = @temp END END --Obtener caracter 1 SELECT @ncar1=m.LETRA FROM @Matriz m WHERE m.FILA = @fila1 AND m.COLUMNA = @columna1; --Obtener caracter 2 SELECT @ncar2=m.LETRA FROM @Matriz m WHERE m.FILA = @fila2 AND m.COLUMNA = @columna2; SET @SalidaEncriptada = @SalidaEncriptada + @ncar1 + @ncar2 SET @pgRow = @pgRow + 1 END RETURN @SalidaEncriptada
Eso es todo amigos. Acá el resultado final.
Espero que les sea de utilidad. Agredezco sus comentarios constructivos.
No funciona esta malo. de que me sirve encriptar si cuando meto el resultado de la encriptacion nuevamente en la funcion no decripta lo encriptado.... revisalo...
ResponderEliminarMarcos la función 'encripta', no está mal. Si quieres desencriptarlo tienes que crear una función para tal fin. En el enlace del inicio del post encontraras información al respecto del algoritmo. Puedes usar esa información y combinarla con este post para crear la funcion de 'desencriptacion'
EliminarSaludos
Gracias
ResponderEliminaralexweb.eu