Paginas

miércoles, 5 de enero de 2011

C#, Clase para generar PIN o clave de N digitos si, solo si N < 64

Cualquier inquietud no duden en preguntar !!!!

using System;
using System.Collections;
using System.Text;
using System.Security.Cryptography;
namespace appCPT
{
    namespace Medios
    {
        /// <summary>
        /// Autor = Diego Fernando Carvajal Rodriguez
        /// Version = 1.0
        /// Contacto = ################
        /// Descripcion = Clase dedicada a generar PIN de citas
        /// </summary>


        public class clPinCita
        {
            #region VariablesPrivadas
            private string sCdnaRtrno;
            private string sDsrden;
            private string sRllno;
            private string sRsltdo;
            private string sTrnca;
            private int idCont;
            private int iRndom;
            private int iCntrol;
            private Random rdmRndom;
            private ArrayList lsDsrden;
            private char[] arcCrcter;
            private byte[] arbSaltBytes;
            private RNGCryptoServiceProvider rng;
            private byte[] arbPlainTextBytes;
            private byte[] arbPlainTextWithSaltBytes;
            private HashAlgorithm hash;
            private byte[] arbHashBytes;
            private byte[] arbHashWithSaltBytes;
            private string sHashValue;
            #endregion
            public clPinCita()
            {
                this.sCdnaRtrno = "";
                this.sRllno = "QWERTYUIOPASDFGHJKLZXCVBNM123456789";
                this.sDsrden = "";
                this.sRsltdo = "";
                this.idCont = 0;
                this.iRndom = 0;
                this.iCntrol = 0;
                this.rdmRndom = new Random();
                this.lsDsrden = new ArrayList();
                this.arcCrcter = null;
            }
            /// <summary>
            /// Metodo para generar el identificador de la cita (BASICO)
            /// </summary>
            /// <param name="sCdna">Concatenacion de informacion para generar PIN unico</param>
            /// <param name="iOrden">Tipo de truncado; 0 == aleatorio; 1 == inicio(3 caractere)+medio(4 caracteres)+fin(3 caracteres); 2 == medio(4 caracteres)+fin(3 caracteres)+inicio(3 caractere); 3 == fin(3 caracteres)+inicio(3 caractere)+medio(4 caracteres)</param>
            /// <param name="iTmnoPIN">Tamaño de caracteres del PIN</param>
            /// <returns>string de 10 carcteres que representa el PIN de la cita</returns>
            public string fnsGenerarPINBasico(string sCdna, int iOrden, int iTmnoPIN)
            {
                this.sCdnaRtrno = "";
                this.sRsltdo = "";
                this.arcCrcter = sCdna.ToUpper().ToCharArray();
                this.iRndom = 0;
                for (this.idCont = 0; this.idCont < this.arcCrcter.Length; this.idCont++)
                {
                    if ((this.arcCrcter[idCont] >= 'A' && this.arcCrcter[idCont] <= 'Z') || (this.arcCrcter[idCont] >= '1' && this.arcCrcter[idCont] <= '9'))
                    {
                        this.sCdnaRtrno = this.sCdnaRtrno + this.arcCrcter[idCont];
                    }
                }
                if (this.sCdnaRtrno.Length < 32)
                {
                    this.arcCrcter = this.sRllno.ToCharArray();
                    do
                    {
                        this.iRndom = this.rdmRndom.Next(0, (this.sRllno.Length-1));
                        this.sCdnaRtrno = this.sCdnaRtrno + this.arcCrcter[this.iRndom];
                    } while (this.sCdnaRtrno.Length < 32);
                    this.sCdnaRtrno = fnsDesordenaCadena(this.sCdnaRtrno);
                }
                return fnsTruncaCadena(this.sRsltdo, iOrden, iTmnoPIN);
            }
            /// <summary>
            /// Metodo para desordenar cadenas
            /// </summary>
            /// <param name="sCdna">cadena a desordenar</param>
            /// <returns>string con la cadena desordenada</returns>
            private string fnsDesordenaCadena(string sCdna)
            {
                this.sDsrden = "";
                this.lsDsrden = new ArrayList();
                this.iRndom = 0;
                this.idCont = 0;
                this.iCntrol = 0;
                this.arcCrcter = sCdna.ToCharArray();
                do
                {
                    if (this.iCntrol == 0)
                    {
                        this.iRndom = this.rdmRndom.Next(this.idCont, (sCdna.Length - 1));
                    }
                    if (this.iCntrol == 1)
                    {
                        this.iRndom = this.rdmRndom.Next(0, this.idCont);
                    }

                    if (!this.lsDsrden.Contains(this.iRndom))
                    {
                        this.sDsrden = this.sDsrden + this.arcCrcter[this.iRndom];
                        this.lsDsrden.Add(this.iRndom);
                        this.idCont = 0;
                    }
                    if (this.idCont == (sCdna.Length - 1))
                    {
                        this.iCntrol = 1;
                    }
                    if (this.idCont == 0)
                    {
                        this.iCntrol = 0;
                    }
                    if (this.iCntrol == 0)
                    {
                        this.idCont++;
                    }
                    if (this.iCntrol == 1)
                    {
                        this.idCont--;
                    }
                } while (this.sDsrden.Length < sCdna.Length);
                return this.sDsrden;
            }
            /// <summary>
            /// Metodo para truncar una cadena
            /// </summary>
            /// <param name="sHash">Cadena a ser truncada</param>
            /// <param name="iOrden">Tipo de truncado; 0 == aleatorio; 1 == inicio(3 caractere)+medio(4 caracteres)+fin(3 caracteres); 2 == medio(4 caracteres)+fin(3 caracteres)+inicio(3 caractere); 3 == fin(3 caracteres)+inicio(3 caractere)+medio(4 caracteres)</param>
            /// <param name="iTmnoPIN">Tamaño de caracteres del PIN</param>
            /// <returns>string de 10 caracteres</returns>
            private string fnsTruncaCadena(string sHash, int iOrden, int iTmnoPIN)
            {
                this.sTrnca = "";
                this.lsDsrden = new ArrayList();
                this.iRndom = 0;
                if (sHash.Length > iTmnoPIN)
                {
                    this.arcCrcter = sHash.ToCharArray();
                    switch (iOrden)
                    {
                        case 0://Aleatorio
                            do
                            {
                                this.iRndom = this.rdmRndom.Next(0, (sHash.Length - 1));
                                if (!this.lsDsrden.Contains(this.iRndom))
                                {
                                    this.sTrnca = this.sTrnca + this.arcCrcter[this.iRndom];
                                    this.lsDsrden.Add(this.iRndom);
                                }
                            } while (this.sTrnca.Length < iTmnoPIN);
                            break;
                        case 1:
                            this.sTrnca = this.sTrnca + this.arcCrcter[0];
                            this.sTrnca = this.sTrnca + this.arcCrcter[1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[2];
                            this.sTrnca = this.sTrnca + this.arcCrcter[((sHash.Length / 2) - 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length / 2) - 1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length / 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[((sHash.Length / 2) + 1)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length - 3)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length - 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[sHash.Length - 1];
                            break;
                        case 2:
                            this.sTrnca = this.sTrnca + this.arcCrcter[((sHash.Length / 2) - 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length / 2) - 1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length / 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[((sHash.Length / 2) + 1)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length - 3)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length - 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[sHash.Length - 1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[0];
                            this.sTrnca = this.sTrnca + this.arcCrcter[1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[2];
                            break;
                        case 3:
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length - 3)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length - 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[sHash.Length - 1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[0];
                            this.sTrnca = this.sTrnca + this.arcCrcter[1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[2];
                            this.sTrnca = this.sTrnca + this.arcCrcter[((sHash.Length / 2) - 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length / 2) - 1];
                            this.sTrnca = this.sTrnca + this.arcCrcter[(sHash.Length / 2)];
                            this.sTrnca = this.sTrnca + this.arcCrcter[((sHash.Length / 2) + 1)];
                            break;
                        default:
                            this.sTrnca = sHash;
                            break;
                    }
                }
                else
                {
                    this.sTrnca = sHash;
                }
                return this.sTrnca;
            }
            /// <summary>
            /// Enumeracion de las distintos algoritmos hash
            /// </summary>
            public enum ProveedorHash
            {
                SHA1,
                SHA256,
                SHA384,
                SHA512,
                MD5
            }
            /// <summary>
            /// Metodo para generar el identificador de la cita (HASH)
            /// </summary>
            /// <param name="sCdna">Concatenacion de informacion para generar PIN unico</param>
            /// <param name="phTpo">Tipo de algoritmo a aplicar</param>
            /// <param name="iOrden">Tipo de truncado; 0 == aleatorio; 1 == inicio(3 caractere)+medio(4 caracteres)+fin(3 caracteres); 2 == medio(4 caracteres)+fin(3 caracteres)+inicio(3 caractere); 3 == fin(3 caracteres)+inicio(3 caractere)+medio(4 caracteres)</param>
            /// <param name="iTmnoPIN">Tamaño de caracteres del PIN</param>
            /// <returns>string con el PIN unico</returns>
            public string fnsGenerarPINHash(string sCdna, ProveedorHash phTpo, int iOrden, int iTmnoPIN)
            {
                this.sHashValue = "";
                this.arbSaltBytes = new byte[8];
                this.rng = new RNGCryptoServiceProvider();
                this.rng.GetNonZeroBytes(this.arbSaltBytes);
                this.arbPlainTextBytes = Encoding.UTF8.GetBytes(sCdna);
                this.arbPlainTextWithSaltBytes = new byte[this.arbPlainTextBytes.Length + this.arbSaltBytes.Length];
                for (this.idCont = 0; this.idCont < this.arbPlainTextBytes.Length; this.idCont++)
                {
                    this.arbPlainTextWithSaltBytes[this.idCont] = this.arbPlainTextBytes[this.idCont];
                }
                for (this.idCont = 0; this.idCont < this.arbSaltBytes.Length; this.idCont++)
                {
                    this.arbPlainTextWithSaltBytes[arbPlainTextBytes.Length + this.idCont] = this.arbSaltBytes[this.idCont];
                }

                switch (phTpo)
                {
                    case ProveedorHash.SHA1:
                        this.hash = new SHA1Managed();
                        break;
                    case ProveedorHash.SHA256:
                        this.hash = new SHA256Managed();
                        break;
                    case ProveedorHash.SHA384:
                        this.hash = new SHA384Managed();
                        break;
                    case ProveedorHash.SHA512:
                        this.hash = new SHA512Managed();
                        break;
                    case ProveedorHash.MD5:
                        this.hash = new MD5CryptoServiceProvider();
                        break;
                }
                this.arbHashBytes = this.hash.ComputeHash(this.arbPlainTextWithSaltBytes);
                this.arbHashWithSaltBytes = new byte[this.arbHashBytes.Length + this.arbSaltBytes.Length];
                for (this.idCont = 0; this.idCont < this.arbHashBytes.Length; this.idCont++)
                {
                    this.arbHashWithSaltBytes[this.idCont] = this.arbHashBytes[this.idCont];
                }
                for (this.idCont = 0; this.idCont < this.arbSaltBytes.Length; this.idCont++)
                {
                    this.arbHashWithSaltBytes[this.arbHashBytes.Length + this.idCont] = this.arbSaltBytes[this.idCont];
                }
                this.sHashValue = Convert.ToBase64String(this.arbHashWithSaltBytes);
                return fnsTruncaCadena(this.sHashValue, iOrden, iTmnoPIN);
            }
        }
    }
}

No hay comentarios:

Publicar un comentario