using System; namespace HRM.BO { public class AES { private int _nNk, _nNb, _nNr; private int[] _nOnBits, _n2Power, _nFKey, _nRKey, _nFTable, _nRTable, _nRCo; private byte[] _bytOnBits, _byt2Power, _nInCo, _nFbSub, _nRbSub, _nPTab, _nLTab, _nFi, _nRi; public AES() { _nInCo=new byte[4]; _nOnBits=new int[32]; _n2Power=new int[32]; _nFKey=new int[128]; _nRKey=new int[120]; _nFTable=new int[256]; _nRTable=new int[256]; _nRCo=new int[30]; _bytOnBits=new byte[8]; _byt2Power=new byte[8]; _nFi=new byte[24]; _nRi=new byte[24]; _nInCo=new byte[4]; _nFbSub=new byte[256]; _nRbSub=new byte[256]; _nPTab=new byte[256]; _nLTab=new byte[256]; _nInCo[0]=0xB; _nInCo[1]=0xD; _nInCo[2]=0x9; _nInCo[3]=0xE; // Could have done this with a loop calculating each value, but simply // assigning the values is quicker - BITS SET FROM RIGHT _bytOnBits[0]=1; // 00000001 _bytOnBits[1]=3; // 00000011 _bytOnBits[2]=7; // 00000111 _bytOnBits[3]=15; // 00001111 _bytOnBits[4]=31; // 00011111 _bytOnBits[5]=63; // 00111111 _bytOnBits[6]=127; // 01111111 _bytOnBits[7]=255; // 11111111 // Could have done this with a loop calculating each value, but simply // assigning the values is quicker - POWERS OF 2 _byt2Power[0]=1; // 00000001 _byt2Power[1]=2; // 00000010 _byt2Power[2]=4; // 00000100 _byt2Power[3]=8; // 00001000 _byt2Power[4]=16; // 00010000 _byt2Power[5]=32; // 00100000 _byt2Power[6]=64; // 01000000 _byt2Power[7]=128; // 10000000 // Could have done this with a loop calculating each value, but simply // assigning the values is quicker - BITS SET FROM RIGHT _nOnBits[0]=1; // 00000000000000000000000000000001 _nOnBits[1]=3; // 00000000000000000000000000000011 _nOnBits[2]=7; // 00000000000000000000000000000111 _nOnBits[3]=15; // 00000000000000000000000000001111 _nOnBits[4]=31; // 00000000000000000000000000011111 _nOnBits[5]=63; // 00000000000000000000000000111111 _nOnBits[6]=127; // 00000000000000000000000001111111 _nOnBits[7]=255; // 00000000000000000000000011111111 _nOnBits[8]=511; // 00000000000000000000000111111111 _nOnBits[9]=023; // 00000000000000000000001111111111 _nOnBits[10]=2047; // 00000000000000000000011111111111 _nOnBits[11]=4095; // 00000000000000000000111111111111 _nOnBits[12]=8191; // 00000000000000000001111111111111 _nOnBits[13]=16383; // 00000000000000000011111111111111 _nOnBits[14]=32767; // 00000000000000000111111111111111 _nOnBits[15]=65535; // 00000000000000001111111111111111 _nOnBits[16]=131071; // 00000000000000011111111111111111 _nOnBits[17]=262143; // 00000000000000111111111111111111 _nOnBits[18]=524287; // 00000000000001111111111111111111 _nOnBits[19]=1048575; // 00000000000011111111111111111111 _nOnBits[20]=2097151; // 00000000000111111111111111111111 _nOnBits[21]=4194303; // 00000000001111111111111111111111 _nOnBits[22]=8388607; // 00000000011111111111111111111111 _nOnBits[23]=16777215; // 00000000111111111111111111111111 _nOnBits[24]=33554431; // 00000001111111111111111111111111 _nOnBits[25]=67108863; // 00000011111111111111111111111111 _nOnBits[26]=134217727; // 00000111111111111111111111111111 _nOnBits[27]=268435455; // 00001111111111111111111111111111 _nOnBits[28]=536870911; // 00011111111111111111111111111111 _nOnBits[29]=1073741823; // 00111111111111111111111111111111 _nOnBits[30]= 2147483647; // 01111111111111111111111111111111 // Could have done this with a loop calculating each value, but simply // assigning the values is quicker - POWERS OF 2 _n2Power[0]=1; // 00000000000000000000000000000001 _n2Power[1]=2; // 00000000000000000000000000000010 _n2Power[2]=4; // 00000000000000000000000000000100 _n2Power[3]=8; // 00000000000000000000000000001000 _n2Power[4]=16; // 00000000000000000000000000010000 _n2Power[5]=32; // 00000000000000000000000000100000 _n2Power[6]=64; // 00000000000000000000000001000000 _n2Power[7]=128; // 00000000000000000000000010000000 _n2Power[8]=256; // 00000000000000000000000100000000 _n2Power[9]=512; // 00000000000000000000001000000000 _n2Power[10]=1024; // 00000000000000000000010000000000 _n2Power[11]=2048; // 00000000000000000000100000000000 _n2Power[12]=4096; // 00000000000000000001000000000000 _n2Power[13]=8192; // 00000000000000000010000000000000 _n2Power[14]=16384; // 00000000000000000100000000000000 _n2Power[15]=32768; // 00000000000000001000000000000000 _n2Power[16]=65536; // 00000000000000010000000000000000 _n2Power[17]=131072; // 00000000000000100000000000000000 _n2Power[18]=262144; // 00000000000001000000000000000000 _n2Power[19]=524288; // 00000000000010000000000000000000 _n2Power[20]=1048576; // 00000000000100000000000000000000 _n2Power[21]=2097152; // 00000000001000000000000000000000 _n2Power[22]=4194304; // 00000000010000000000000000000000 _n2Power[23]=8388608; // 00000000100000000000000000000000 _n2Power[24]=16777216; // 00000001000000000000000000000000 _n2Power[25]=33554432; // 00000010000000000000000000000000 _n2Power[26]=67108864; // 00000100000000000000000000000000 _n2Power[27]=134217728; // 00001000000000000000000000000000 _n2Power[28]=268435456; // 00010000000000000000000000000000 _n2Power[29]=536870912; // 00100000000000000000000000000000 _n2Power[30]=1073741824; // 01000000000000000000000000000000 } private int LShift(int nValue, int nShiftBits) { return (nValue<<nShiftBits); } //******************************************************************************* // RShift (FUNCTION) //******************************************************************************* private int RShift(int lValue, int iShiftBits) { int nRShift=0; if(iShiftBits==0) { nRShift=lValue; } else if(iShiftBits==31) { if((lValue & -2147483648)!=0) {nRShift=1;} else {nRShift=0;} } else if(iShiftBits<0 || iShiftBits>31) { nRShift=-1; } nRShift=((lValue & 2147483646)/_n2Power[iShiftBits]); if((lValue & -2147483648)!=0) { nRShift=(nRShift | (1073741824/_n2Power[iShiftBits-1])); } return nRShift; } //******************************************************************************* // LShiftByte (FUNCTION) //******************************************************************************* private byte LShiftByte(byte bytValue, byte bytShiftBits) { byte nLShiftByte=0; if(bytShiftBits==0) { nLShiftByte=bytValue; } else if(bytShiftBits==7) { if((bytValue & 1)!=0) {nLShiftByte = 0x80;} else {nLShiftByte=0;} } else if(bytShiftBits<0 || bytShiftBits>7) { nLShiftByte=0; } nLShiftByte=(byte)((bytValue & _bytOnBits[7-bytShiftBits])*_byt2Power[bytShiftBits]); return nLShiftByte; } //******************************************************************************* // RShiftByte (FUNCTION) //******************************************************************************* private byte RShiftByte(byte bytValue, byte bytShiftBits) { byte nRShiftByte=0; if(bytShiftBits==0) { nRShiftByte=bytValue; } else if(bytShiftBits==7) { if((bytValue & 0x80)!=0) {nRShiftByte=1;} else {nRShiftByte=0;} } else if(bytShiftBits<0 || bytShiftBits>7) { nRShiftByte=0; } nRShiftByte=(byte)(bytValue/_byt2Power[bytShiftBits]); return nRShiftByte; } //******************************************************************************* // RotateLeft (FUNCTION) //******************************************************************************* private int RotateLeft(int lValue, int iShiftBits) { return (LShift(lValue, iShiftBits)|RShift(lValue, (int)(32-iShiftBits))); } ////******************************************************************************* //// RotateLeftByte (FUNCTION) //******************************************************************************* private byte RotateLeftByte(byte bytValue, byte bytShiftBits) { return (byte)(LShiftByte(bytValue, bytShiftBits) | RShiftByte(bytValue, (byte)(8-bytShiftBits))); } //******************************************************************************* // Pack (FUNCTION) //******************************************************************************* private int Pack(byte[] b) { int nTemp=0, nPack=0; for(int nCount=0; nCount<=3; nCount++) { nTemp=b[nCount]; nPack=nPack | LShift(nTemp, (int)(nCount*8)); } return nPack; } //******************************************************************************* // PackFrom (FUNCTION) //******************************************************************************* private int PackFrom(byte[] b, int k) { int nPackFrom=0, nTemp=0; for(int nCount=0; nCount<=3; nCount++) { nTemp=b[nCount+k]; nPackFrom=nPackFrom | LShift(nTemp, (int)(nCount*8)); } return nPackFrom; } //******************************************************************************* // Unpack (SUB) //******************************************************************************* private void Unpack(int a, ref byte[] b) { b[0]=(byte)(a & _nOnBits[7]); b[1]=(byte)(RShift(a, 8) & _nOnBits[7]); b[2]=(byte)(RShift(a, 16) & _nOnBits[7]); b[3]=(byte)(RShift(a, 24) & _nOnBits[7]); } //******************************************************************************* // UnpackFrom (SUB) //******************************************************************************* private void UnpackFrom(int a, ref byte[] b, int k) { b[0+k]=(byte)(a & _nOnBits[7]); b[1+k]=(byte)(RShift(a, 8) & _nOnBits[7]); b[2+k]=(byte)(RShift(a, 16) & _nOnBits[7]); b[3+k]=(byte)(RShift(a, 24) & _nOnBits[7]); } //******************************************************************************* // xtime (FUNCTION) //******************************************************************************* private byte xTime(byte a) { byte b=0; if((a & 0x80)!=0) {b=0x1B;} else {b=0;} a=LShiftByte(a, 1); a=(byte)(a^b); return a; } //******************************************************************************* // bmul (FUNCTION) //******************************************************************************* private byte bMul(byte x, byte Y) { byte nbmul=0; if(x!=0 && Y!=0) { nbmul=(byte)(_nPTab[(_nLTab[x]+ _nLTab[Y]) % 255]); } return nbmul; } //******************************************************************************* // SubByte (FUNCTION) //******************************************************************************* private int SubByte(int a) { byte[] b=new byte[4]; Unpack(a, ref b); b[0]=_nFbSub[b[0]]; b[1]=_nFbSub[b[1]]; b[2]=_nFbSub[b[2]]; b[3]=_nFbSub[b[3]]; return (Pack(b)); } //******************************************************************************* // product (FUNCTION) //******************************************************************************* private int Product(int x, int y) { byte[] xb=new Byte[4]; byte[] yb=new Byte[4]; Unpack(x, ref xb); Unpack(y, ref yb); return (bMul(xb[0], yb[0]) ^ bMul(xb[1], yb[1]) ^ bMul(xb[2], yb[2]) ^ bMul(xb[3], yb[3])); } //******************************************************************************* // InvMixCol (FUNCTION) //******************************************************************************* private int InvMixCol(int x) { int m=0; byte[] b=new byte[4]; m=Pack(_nInCo); b[3]=(byte)Product(m, x); m=RotateLeft(m, 24); b[2]=(byte)Product(m, x); m=RotateLeft(m, 24); b[1]=(byte)Product(m, x); m=RotateLeft(m, 24); b[0]=(byte)Product(m, x); return Pack(b); } //******************************************************************************* // ByteSub (FUNCTION) //******************************************************************************* private byte ByteSub(byte x) { byte Y=0; Y=_nPTab[255-_nLTab[x]]; x=Y; x=RotateLeftByte(x, 1); Y=(byte)(Y ^ x); x=RotateLeftByte(x, 1); Y=(byte)(Y ^ x); x=RotateLeftByte(x, 1); Y=(byte)(Y ^ x); x=RotateLeftByte(x, 1); Y=(byte)(Y ^ x); Y=(byte)(Y ^ 0x63); return Y; } //******************************************************************************* // gentables (SUB) //******************************************************************************* private void GenTables() { int i=0; byte Y=0, ib=0; byte[] b=new byte[4]; _nLTab[0]=0; _nPTab[0]=1; _nLTab[1]=0; _nPTab[1]=3; _nLTab[3]=1; for(i=2; i<=255; i++) { _nPTab[i]= (byte)(_nPTab[i-1] ^ xTime(_nPTab[i-1])); _nLTab[_nPTab[i]]=(byte)i; } _nFbSub[0]=0x63; _nRbSub[0x63]=0; for(i=1; i<=255; i++) { ib=(byte)i; Y=ByteSub(ib); _nFbSub[i]=Y; _nRbSub[Y]=(byte)i; } Y=1; for(i=0; i<=29; i++) { _nRCo[i]=Y; Y=xTime(Y); } for(i=0; i<=255; i++) { Y=_nFbSub[i]; b[3]=(byte)(Y ^ xTime(Y)); b[2]=Y; b[1]=Y; b[0]=xTime(Y); _nFTable[i]=Pack(b); Y=_nRbSub[i]; b[3]=bMul(_nInCo[0], Y); b[2]=bMul(_nInCo[1], Y); b[1]=bMul(_nInCo[2], Y); b[0]=bMul(_nInCo[3], Y); _nRTable[i]=Pack(b); } } //******************************************************************************* // gkey (SUB) //******************************************************************************* private void GenKey(int nb, int nk, byte[] KEY) { int i=0, j=0, k=0, m=0, N=0, C1=0, C2=0, C3=0; int[] CipherKey=new int[8]; _nNb = nb; _nNk = nk; if(_nNb>=_nNk) {_nNr=6+_nNb;} else {_nNr=6+_nNk;} C1 = 1; if(_nNb<8) {C2=2; C3=3;} else {C2=3; C3=4;} for(j=0; j<=(nb-1); j++) { m=j*3; _nFi[m] =(byte)((j +C1) % nb); _nFi[m+1]=(byte)((j +C2) % nb); _nFi[m+2]=(byte)((j +C3) % nb); _nRi[m] =(byte)((nb+j-C1) % nb); _nRi[m+1]=(byte)((nb+j-C2) % nb); _nRi[m+2]=(byte)((nb+j-C3) % nb); } N=_nNb*(_nNr+1); for(i=0; i<=(_nNk-1); i++) { j=i*4; CipherKey[i]= PackFrom(KEY, j); } for(i=0; i<=(_nNk-1); i++) { _nFKey[i]=CipherKey[i]; } j=_nNk; k=0; while(j<N) { _nFKey[j]=_nFKey[j-_nNk] ^ SubByte(RotateLeft(_nFKey[j-1], 24)) ^ _nRCo[k]; if(_nNk<=6) { i=1; while((i<_nNk) && ((i+j)< N)) { _nFKey[i+j]=_nFKey[i+j-_nNk] ^ _nFKey[i+j-1]; i=i+1; } } else { // Problem fixed here i=1; while((i<4) && (i+j)<N) { _nFKey[i+j]=_nFKey[i+j-_nNk] ^ _nFKey[i+j-1]; i=i+1; } if((j+4)<N) { _nFKey[j+4]=_nFKey[j+4-_nNk] ^ SubByte(_nFKey[j+3]); } i = 5; while((i<_nNk) && (i+j)<N) { _nFKey[i+j]=_nFKey[i+j-_nNk] ^ _nFKey[i+j-1]; i=i+1; } } j=j+_nNk; k=k+1; } for(j=0; j<=(_nNb-1); j++) { _nRKey[j+N-nb]=_nFKey[j]; } i = _nNb; while(i<(N-_nNb)) { k=N-_nNb-i; for(j=0; j<=(_nNb-1); j++) { _nRKey[k+j]=InvMixCol(_nFKey[i+j]); } i=i+_nNb; } j=N-_nNb; while(j<N) { _nRKey[j-N+_nNb]=_nFKey[j]; j=j+1; } } //******************************************************************************* // encrypt (SUB) //******************************************************************************* private void Encrypt(byte[] buff) { int i=0, j=0, k=0, m=0; int[] a=new int[8]; int[] b=new int[8]; int[] x, Y, t; for(i=0; i<=(_nNb-1); i++) { j=i*4; a[i]=PackFrom(buff, j); a[i]=a[i] ^ _nFKey[i]; } k=_nNb; x=a; Y=b; for(i=1; i<=(_nNr-1); i++) { for(j=0; j<=(_nNb-1); j++) { m=j*3; Y[j]=_nFKey[k] ^ _nFTable[x[j] & _nOnBits[7]] ^ RotateLeft(_nFTable[RShift(x[_nFi[m]], 8) & _nOnBits[7]], 8) ^ RotateLeft(_nFTable[RShift(x[_nFi[m+1]], 16) & _nOnBits[7]], 16) ^ RotateLeft(_nFTable[RShift(x[_nFi[m+2]], 24) & _nOnBits[7]], 24); k=k+1; } t=x; x=Y; Y=t; } for(j=0; j<=(_nNb-1); j++) { m=j*3; Y[j]=_nFKey[k] ^ _nFbSub[x[j] & _nOnBits[7]] ^ RotateLeft(_nFbSub[RShift(x[_nFi[m]], 8) & _nOnBits[7]], 8) ^ RotateLeft(_nFbSub[RShift(x[_nFi[m+1]], 16) & _nOnBits[7]], 16) ^ RotateLeft(_nFbSub[RShift(x[_nFi[m+2]], 24) & _nOnBits[7]], 24); k = k + 1; } for(i=0; i<=(_nNb-1); i++) { j=i*4; UnpackFrom(Y[i], ref buff, j); x[i]=0; Y[i]=0; } } //******************************************************************************* // decrypt (SUB) //******************************************************************************* private void Decrypt(byte[] buff) { int i=0, j=0, k=0, m=0; int [] a=new int[8]; int [] b=new int[8]; int [] x, Y, t; for(i=0; i<=(_nNb-1); i++) { j=i*4; a[i]=PackFrom(buff, j); a[i]=a[i] ^ _nRKey[i]; } k=_nNb; x=a; Y=b; for(i=1; i<=(_nNr-1); i++) { for(j=0; j<=(_nNb-1); j++) { m=j*3; Y[j]=_nRKey[k] ^ _nRTable[x[j] & _nOnBits[7]] ^ RotateLeft(_nRTable[RShift(x[_nRi[m]], 8) & _nOnBits[7]], 8) ^ RotateLeft(_nRTable[RShift(x[_nRi[m+1]], 16) & _nOnBits[7]], 16) ^ RotateLeft(_nRTable[RShift(x[_nRi[m+2]], 24) & _nOnBits[7]], 24); k = k + 1; } t = x; x = Y; Y = t; } for(j=0; j<=(_nNb-1); j++) { m=j*3; Y[j]=_nRKey[k] ^ _nRbSub[x[j] & _nOnBits[7]] ^ RotateLeft(_nRbSub[RShift(x[_nRi[m]], 8) & _nOnBits[7]], 8) ^ RotateLeft(_nRbSub[RShift(x[_nRi[m+1]], 16) & _nOnBits[7]], 16) ^ RotateLeft(_nRbSub[RShift(x[_nRi[m+2]], 24) & _nOnBits[7]], 24); k = k + 1; } for(i=0; i<=(_nNb-1); i++) { j=i*4; UnpackFrom(Y[i], ref buff, j); x[i]=0; Y[i]=0; } } //******************************************************************************* // IsInitialized (FUNCTION) //******************************************************************************* private bool IsInitialized(byte [] bArray) { return (bArray.Length>0); } //******************************************************************************* // EncryptData (FUNCTION) // Takes the message, whatever the size, and password in one call and does // everything for you to return an encoded/encrypted message //******************************************************************************* public byte[] EncryptData(byte[] bytMessage, byte [] bytPassword) { byte[] bytIn, bytOut; byte[] bytLen=new byte[4]; byte[] bytKey=new byte[32]; byte[] bytTemp=new byte[32]; int lCount=0, lLength=0, lEncodedLength=0; if(!IsInitialized(bytMessage)) { return bytMessage; } if(!IsInitialized(bytPassword)) { return bytPassword; } // Use first 32 bytes of the password for the key for(lCount=0; lCount<bytPassword.Length; lCount++) { bytKey[lCount]=bytPassword[lCount]; if(lCount==31) { break; } } // Prepare the key; assume 256 bit block and key size GenTables(); GenKey(8, 8, bytKey); // We are going to put the message size on the front of the message // in the first 4 bytes. If the length is more than a max int we are // in trouble lLength=bytMessage.Length; lEncodedLength=lLength+4; // The encoded length includes the 4 bytes stuffed on the front // and is padded out to be modulus 32 if((lEncodedLength % 32)!= 0) { lEncodedLength=lEncodedLength+32-(lEncodedLength % 32); } bytIn=new byte[lEncodedLength]; bytOut=new byte[lEncodedLength]; IntToByte(lLength, ref bytIn); //bytMessage.CopyTo(bytIn, 4); Copy(ref bytIn, 4, bytMessage, 0, lLength); for(lCount=0; lCount<=(lEncodedLength-1); lCount=lCount+32) { Copy(ref bytTemp, 0, bytIn, lCount,32); //Encrypt Block by Block Encrypt(bytTemp); Copy(ref bytOut, lCount, bytTemp, 0, 32); } return bytOut; } /// <summary> /// Decrypt Function /Oposite of Encrypt /// </summary> /// <param name="bytIn"></param> /// <param name="bytPassword"></param> /// <returns></returns> public byte[] DecryptData(byte[] bytIn, byte[] bytPassword) { byte[] bytMessage, bytOut; byte[] bytLen=new byte[4]; byte[] bytKey=new byte[32]; byte[] bytTemp=new byte[32]; int lCount=0, lLength=0, lEncodedLength=0; if(!IsInitialized(bytIn)) { return bytIn; } if(!IsInitialized(bytPassword)) { return bytPassword; } lEncodedLength=bytIn.Length; if((lEncodedLength % 32) !=0) { return bytIn; } // Use first 32 bytes of the password for the key for(lCount=0; lCount<bytPassword.Length; lCount++) { bytKey[lCount]=bytPassword[lCount]; if(lCount==31) { break; } } // Prepare the key; assume 256 bit block and key size GenTables(); GenKey(8, 8, bytKey); // The output array needs to be the same size as the input array bytOut=new byte[lEncodedLength]; for(lCount=0; lCount<lEncodedLength; lCount=lCount+32) { Copy(ref bytTemp, 0, bytIn, lCount, 32); //Decrypt Block by Block Decrypt(bytTemp); Copy(ref bytOut, lCount, bytTemp, 0, 32); } lLength=ByteToInt(bytOut); // Make sure the length is consistent with our data if(lLength>lEncodedLength-4) { return bytIn; } // Prepare the output message byte array bytMessage=new byte[lLength]; Copy(ref bytMessage, 0, bytOut, 4, lLength); return bytMessage; } //Sum Function to help CopyMemory, Hex, Int, Byte Conversion private void Copy(ref byte[] Destination, int DestIndex, byte[] Source, int SrcIndex, int Length) { for(int j=0; j<Length; j++) { Destination[DestIndex+j]=Source[j+SrcIndex]; } } private void IntToByte(int nNumber, ref byte[] bytOut) { string sText=Convert.ToString(nNumber,16); if(sText.Length<8) { sText=new String('0',(8-sText.Length))+sText; } char[] cChars=sText.ToCharArray(); byte[] nByteOut=new byte[4]; for(int nCount=0; nCount<cChars.Length; nCount=nCount+2) { byte b=(byte)(Convert.ToByte(cChars[nCount].ToString(), 16)<<4); b=(byte)(b | Convert.ToByte(cChars[nCount+1].ToString(), 16) & 0x0F); nByteOut[nCount/2]=b; } bytOut[3]=nByteOut[0]; bytOut[2]=nByteOut[1]; bytOut[1]=nByteOut[2]; bytOut[0]=nByteOut[3]; return; } private int ByteToInt(byte[] bytIn) { int nNumber=0; nNumber=bytIn[3]; nNumber=(nNumber<<8) | bytIn[2]; nNumber=(nNumber<<8) | bytIn[1]; nNumber=(nNumber<<8) | bytIn[0]; return nNumber; } public byte[] StringToByte(string sText) { int nCount=0; char[] cChars=new char[sText.Length]; byte[] nByteOut=new byte[2*cChars.Length]; cChars=sText.ToCharArray(); for(nCount=0; nCount<nByteOut.Length; nCount=nCount+2) { nByteOut[nCount]=(byte)cChars[nCount/2]; } return nByteOut; } public string ByteToHexString(byte[] nBytes) { char[] HexDigits ={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; char[] cChrs = new char[nBytes.Length * 2]; for(int i=0; i<nBytes.Length; i++) { int b=nBytes[i]; cChrs[i*2]=HexDigits[b >> 4]; cChrs[i*2+1]=HexDigits[b & 0xF]; } return new string(cChrs); } public string ByteToString(byte[] nBytes) { char[] cChrs = new char[nBytes.Length/2]; for(int i=0; i<nBytes.Length; i=i+2) { cChrs[i/2]=(char)nBytes[i]; } return new string(cChrs); } public byte[] HexToByte(string sHexData) { byte[] nByteOut=new byte[sHexData.Length/2]; char[] cChars=sHexData.ToCharArray(); for(int nCount=0; nCount<cChars.Length; nCount=nCount+2) { byte b=(byte)(Convert.ToByte(cChars[nCount].ToString(), 16)<<4); b=(byte)(b | Convert.ToByte(cChars[nCount+1].ToString(), 16) & 0x0F); nByteOut[nCount/2]=b; } return nByteOut; } } }