Files
RepoMain/ZCppMain/ZMainEnc.H

1748 lines
64 KiB
C++

#ifndef __ZCPPMAIN__ZMAINENC_H__
#define __ZCPPMAIN__ZMAINENC_H__
#include "ZCppMain/ZMainHead.H"
namespace ZNsMain
{
namespace ZNsEnc
{
template<typename TTypInt> char ZftGetHexOfChar(TTypInt AI_IntVal)
{
// must be AI_IntVal>=0 || AI_IntVal<16
if(AI_IntVal<10)
return '0'+AI_IntVal;
else return 'A'+(AI_IntVal-10);
}/*
template<typename TTypInt> char ZftGetHexOfChar(TTypInt AI_IntVal) */
inline char ZfGetCharOfHex(char AC_HexChar)
{
if(AC_HexChar>='0' && AC_HexChar<='9') return AC_HexChar-'0' ;
if(AC_HexChar>='A' && AC_HexChar<='Z') return AC_HexChar-'A'+10;
if(AC_HexChar>='a' && AC_HexChar<='z') return AC_HexChar-'a'+10;
return 0; // 이 부분이 수행되게 해서는 안된다.
}/*
inline char ZfGetCharOfHex(char AC_HexChar)*/
inline ZTypUChar ZfGetUCharOfHex(ZTypUChar AUC_HexChar)
{
if(AUC_HexChar>='0' && AUC_HexChar<='9') return AUC_HexChar-'0' ;
if(AUC_HexChar>='A' && AUC_HexChar<='Z') return AUC_HexChar-'A'+10;
if(AUC_HexChar>='a' && AUC_HexChar<='z') return AUC_HexChar-'a'+10;
return 0; // 이 부분이 수행되게 해서는 안된다.
}/*
inline ZTypUChar ZfGetUCharOfHex(ZTypUChar AUC_HexChar)*/
template<typename TString> TString& ZftGetUrlEnc
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc)
{
typedef unsigned char ZTypUChar;
if(AL_Length<0)
{
ARR_CStringEnc.Invalidate(0); return ARR_CStringEnc;
}
/*///////////*/
char *VPC_Encode, VCA_Buff[2+1];
ZTypUChar c=0; int i=0, j=0 ;
ARR_CStringEnc.ReAlloc(AL_Length*3+1) ;
ARR_CStringEnc.Invalidate(0) ;
VPC_Encode = (char*)ARR_CStringEnc ;
if(APC_Origin==0 || VPC_Encode==0)
return ARR_CStringEnc;
/*++++++++++++++++++++++++++++++*/
for(i = j = 0; APC_Origin[i]; i++)
{
c = (ZTypUChar)APC_Origin[i];
/*///////////////////////////////////////////////////////////
qDecoder 라이브러리에 있던 코드
'\\' 문자를 encode 하지 않으므로 약간 바꾼다.
if((c >= '0') && (c <= '9')) VPC_Encode[j++] = c;
else if((c >= 'A') && (c <= 'Z')) VPC_Encode[j++] = c;
else if((c >= 'a') && (c <= 'z')) VPC_Encode[j++] = c;
else if((c == '@') || (c == '.') || (c == '/') || (c == '\\')
|| (c == '-') || (c == '_') || (c == ':') )
VPC_Encode[j++] = c;
else
{
sprintf(VCA_Buff, "%02x", c);
VPC_Encode[j++] = '%';
VPC_Encode[j++] = VCA_Buff[0];
VPC_Encode[j++] = VCA_Buff[1];
}
//else
///////////////////////////////////////////////////////////*/
if ((c >= '0') && (c <= '9')) VPC_Encode[j++] = c;
else if((c >= 'A') && (c <= 'Z')) VPC_Encode[j++] = c;
else if((c >= 'a') && (c <= 'z')) VPC_Encode[j++] = c;
else if((c == '@') || (c == '.') || (c == '/')
|| (c == '-') || (c == '_') || (c == ':') )
VPC_Encode[j++] = c;
else if(c == '\\')
{
VPC_Encode[j++] = '%';
VPC_Encode[j++] = '5';
VPC_Encode[j++] = 'c';
// VPC_Encode[j++] = 'C'; 라 해도
// URL 디코딩한 결과는 같다.
}
else
{
::sprintf(VCA_Buff, "%02x", c);
VPC_Encode[j++] = '%' ;
VPC_Encode[j++] = VCA_Buff[0] ;
VPC_Encode[j++] = VCA_Buff[1] ;
}/*
else*/
}/*
for(i = j = 0; APC_Origin[i]; i++) */
VPC_Encode[j]='\0'; ARR_CStringEnc.CorrectLength(j-1); return ARR_CStringEnc;
}/*
template<typename TString> TString& ZftGetUrlEnc
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc) */
template<typename TString> TString& ZftGetUrlEnc(const char* APC_Origin, TString& ARR_CStringEnc)
{
return ZftGetUrlEnc(APC_Origin, ZNsMain::ZftLength(APC_Origin), RR(ARR_CStringEnc));
}/*
template<typename TString> TString& ZftGetUrlEnc(const char* APC_Origin, TString& ARR_CStringEnc) */
template<typename TString> TString& ZftGetUrlEnc(TString& ARR_CStringData)
{
// ARR_CStringEnc 이 원본 문자열이며 이 문자열을
// 인코딩한 것은 ARR_CStringEnc 에 또 전달한다.
TString VO_CStringEnc; ZftGetUrlEnc
(
ARR_CStringData.data(),
ARR_CStringData.size(),
RR(VO_CStringEnc)
);
///////////////////////////////////
return ARR_CStringData = VO_CStringEnc;
}/*
template<typename TString> TString& ZftGetUrlEnc(CString& ARR_CStringData) */
template<typename TypeChar> TypeChar* ZftGetUrlDec(TypeChar* APC_Origin, long& ARRL_Length)
{
class ZCHelpHex
{
public:
static inline TypeChar ZftGetHexOfChar(TypeChar AC_HexUp, TypeChar AC_HexLow)
{
char VC_Digit = 0;
VC_Digit = 16 * (AC_HexUp >= 'A' ? ((AC_HexUp & 0xdf) - 'A') + 10 : (AC_HexUp - '0'));
VC_Digit += (AC_HexLow >= 'A' ? ((AC_HexLow & 0xdf) - 'A') + 10 : (AC_HexLow - '0'));
return (VC_Digit);
}/*
static inline TypeChar ZftGetHexOfChar(TypeChar AC_HexUp, TypeChar AC_HexLow)*/
public:
};/*
class ZCHelpHex*/
if(ARRL_Length<1) return 0;
int i=0; int j=0;
for(i = j = 0; j<ARRL_Length; i++, j++)
{
switch(APC_Origin[j])
{
case '+':
{
APC_Origin[i] = ' '; break;
}
case '%':
{
APC_Origin[i] = ZCHelpHex::ZftGetHexOfChar
( APC_Origin[j + 1], APC_Origin[j + 2] );
j += 2; break;
}
default:
{
APC_Origin[i] = APC_Origin[j]; break;
}/*
default:*/
}/*
switch(APC_Origin[j])*/
}/*
for(i = j = 0; j<ARRL_Length; i++, j++) */
APC_Origin[ARRL_Length=i]='\0'; return APC_Origin;
}/*
template<typename TypeChar> TypeChar* ZftGetUrlDec(TypeChar* APC_Origin, long& ARRL_Length) */
template<typename TString> TString& ZftGetUrlDec(TString& ARR_CStringDec)
{
long VL_DecSize=ARR_CStringDec.size();
ZftGetUrlDec(ARR_CStringDec.c_str(), RR(VL_DecSize));
ARR_CStringDec.Invalid(VL_DecSize); return ARR_CStringDec;
}/*
template<typename TString> TString& ZftGetUrlDec(TString& ARR_CStringDec) */
template<typename TString> TString& ZftGetUrlUCS2Enc
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc)
{
/*///////////////////////////////////////////////////////////////////////////
■ APC_Origin 을 UCS2 UNICODE 라 했을 때, 2 바이트씩 끊어서
"%u" 로 시작하는 URL 포맷으로 바꾼다. 그래서 javascript 의 escape() 함수가
이 형식의 값을 반환한다. 닷넷 사이트에서 주로 이 형식으로 검색어를 사용한
다.
■ Window 에서 문자셋 CP949 를 이 함수에서 인식하는 UCS2 UNICODE 로 바꾸려면
우선 iconv 라이브러리로 "CP949" 문자열을 "UCS-2" 로 바꾸어주고 이 문자열
을 2 바이트씩 host byte 로 변환시켜주어야 한다.
-- 2008-12-05 01:55:00
※ Window 에서는 iconv 라이브러리로 "CP949" 문자열을 "UTF-16LE" 로 바꾸어
주면 된다.
-- 2009-01-08 23:23:00
■ 2 바이트가 6 바이트로 표현되니까 길이가 3 배 늘어나다.
■ 유니코드(UTF16) <--> UTF8
int WideCharToMultiByte
(
UINT CodePage , // code page
DWORD dwFlags , // performance and mapping flags
LPCWSTR lpWideCharStr , // wide-character string
int cchWideChar , // number of chars in string
LPSTR lpMultiByteStr, // buffer for new string
int cbMultiByte , // size of buffer
LPCSTR lpDefaultChar , // default for unmappable chars
LPBOOL lpUsedDefaultChar // set when default char used
);
이 함수의 첫번째 매개변수 CodePage에 CP_UTF8를 할당하여 사용합니다
IN http://blog.naver.com/zetman99?Redirect=Log&logNo=110027694397
-- 2009-01-08 15:38:00
///////////////////////////////////////////////////////////////////////////*/
long VL_Count = AL_Length/2 ;
if(VL_Count<1) return ARR_CStringEnc;
using ZNsMain::ZNsEnc::ZftGetHexOfChar ;
ARR_CStringEnc.resize(VL_Count*6, ' '); // UCS2 문자 하나가 6 바이트로 표현된다.
char* VPC_Enc = ARR_CStringEnc.data() ;
::uint16_t* VPUI_UCS2= (::uint16_t*)APC_Origin;
::uint16_t VUI_Temp = 0 ;
for(long i=0; i<VL_Count; ++i)
{
VUI_Temp = *VPUI_UCS2++ ;
/* 아래 (::uint16_t) 을 명시적으로 사용했음에 주의.
이 코드가 없으면 VUI_Temp 의 Shift 연산 결과가
::uint16_t 형이 아니고 int 형으로 되버리니까, 이
상태에서 다시 >>12 을 수행하면 원래 값과 같아져 버린다!
*/
*VPC_Enc++ = '%';
*VPC_Enc++ = 'u';
*VPC_Enc++ = ZftGetHexOfChar((::uint16_t) VUI_Temp >>12);
*VPC_Enc++ = ZftGetHexOfChar((::uint16_t)(VUI_Temp<<4 )>>12);
*VPC_Enc++ = ZftGetHexOfChar((::uint16_t)(VUI_Temp<<8 )>>12);
*VPC_Enc++ = ZftGetHexOfChar((::uint16_t)(VUI_Temp<<12)>>12);
}/*
for(long i=0; i<VL_Count; ++i)*/
return ARR_CStringEnc;
}/*
template<typename TString> TString& ZftGetUrlUCS2Enc
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc) */
template<typename TypeChar> TypeChar*
ZftGetUrlUCS2Dec(TypeChar* APC_Origin, long& ARRL_Length)
{
long VL_Count=ARRL_Length/6;
if(VL_Count<1) return APC_Origin;
using ZNsMain::ZNsEnc::ZfGetCharOfHex ;
char* VPC_Enc = APC_Origin ;
::uint16_t* VPUI_UCS2= (::uint16_t*)APC_Origin;
::uint16_t VUI_Temp = 0 ;
for(long i=0; i<VL_Count; ++i)
{
VPC_Enc+=2; // "%u" 를 건너뛴다.
VUI_Temp += ::uint16_t(ZfGetCharOfHex(*VPC_Enc++))*16*16*16;
VUI_Temp += ::uint16_t(ZfGetCharOfHex(*VPC_Enc++))*16*16 ;
VUI_Temp += ::uint16_t(ZfGetCharOfHex(*VPC_Enc++))*16 ;
VUI_Temp += ::uint16_t(ZfGetCharOfHex(*VPC_Enc++)) ;
*VPUI_UCS2++=VUI_Temp; VUI_Temp=0;
}/*
for(long i=0; i<VL_Count; ++i)*/
ARRL_Length=VL_Count*2; return APC_Origin;
}/*
template<typename TypeChar> TypeChar*
ZftGetUrlUCS2Dec(TypeChar* APC_Origin, long& ARRL_Length) */
template<typename TString> TString& ZftGetUrlUCS2Dec(TString& ARR_CStringDec)
{
long VL_Length = ARR_CStringDec.size() ;
ZftGetUrlUCS2Dec
( ARR_CStringDec.data(), RR(VL_Length) );
ARR_CStringDec.resize(VL_Length,' ') ;
return ARR_CStringDec;
}/*
template<typename TString> TString& ZftGetUrlUCS2Dec(TString& ARR_CStringDec) */
template<typename TypeChar> const TypeChar* ZftGetBase64Table()
{
const TypeChar* CPC_Base64Table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
return CPC_Base64Table;
}/*
template<typename TypeChar> const TypeChar* ZftGetBase64Table()*/
template<typename TString> char* ZftGetBase64Enc(
const unsigned char *APC_Origin, long AL_Length,TString& ARR_CStringEnc)
{
// APC_Origin 을 base64 로 인코딩해서 ARR_CStringEnc 에 덧붙인다.
typedef unsigned char ZTypUChar;
ZTypUChar *VPC_Out, *VPC_Pos;
const ZTypUChar *VPC_End, *VCA_In ;
long VL_OutLen, VL_LineLen, VL_PrevSize = ARR_CStringEnc.size();
VL_OutLen = AL_Length * 4 / 3 + 4; // 3-byte blocks to 4-byte
VL_OutLen += VL_OutLen / 72 ; // line feeds
ARR_CStringEnc.resize(VL_PrevSize+VL_OutLen,' ');
VPC_Out = (ZTypUChar*)(ARR_CStringEnc.c_str()+VL_PrevSize);
if(VPC_Out == NULL)
{
ARR_CStringEnc.resize(VL_PrevSize); return NULL;
}/*
if(VPC_Out == NULL)*/
VPC_End = APC_Origin + AL_Length;
VCA_In = APC_Origin ;
VPC_Pos = VPC_Out ;
VL_LineLen= 0 ;
const ZTypUChar* CPC_Base64Table = (ZTypUChar*)ZftGetBase64Table<char>();
while(VPC_End-VCA_In>=3)
{
*VPC_Pos++ = CPC_Base64Table[VCA_In[0] >> 2];
*VPC_Pos++ = CPC_Base64Table[((VCA_In[0] & 0x03) << 4) | (VCA_In[1] >> 4)];
*VPC_Pos++ = CPC_Base64Table[((VCA_In[1] & 0x0f) << 2) | (VCA_In[2] >> 6)];
*VPC_Pos++ = CPC_Base64Table[VCA_In[2] & 0x3f];
VCA_In += 3; VL_LineLen += 4;
const int CI_LineUnit=72;
if(VL_LineLen>=CI_LineUnit)
{
*VPC_Pos++ = '\n'; VL_LineLen = 0;
}
/*///////////////////////*/
}/*
while(VPC_End-VCA_In>=3)*/
if(VPC_End-VCA_In)
{
*VPC_Pos++ = CPC_Base64Table[VCA_In[0] >> 2];
if (VPC_End - VCA_In == 1)
{
*VPC_Pos++ = CPC_Base64Table[(VCA_In[0] & 0x03) << 4];
*VPC_Pos++ = '=';
}
else
{
*VPC_Pos++ = CPC_Base64Table[((VCA_In[0] & 0x03) << 4) |
(VCA_In[1] >> 4)];
*VPC_Pos++ = CPC_Base64Table[(VCA_In[1] & 0x0f) << 2];
}/*
else*/
*VPC_Pos++ = '=';
VL_LineLen += 4 ;
}/*
if(VPC_End-VCA_In)*/
/* if(VL_LineLen>0) *VPC_Pos++ = '\n'; */
ARR_CStringEnc.
resize(VL_PrevSize+(VPC_Pos-VPC_Out), '=');
return (char*)VPC_Out;
}/*
template<typename TString> char* ZftGetBase64Enc
(const unsigned char *APC_Origin, long AL_Length, TString& ARR_CStringEnc) */
template<typename TString> char* ZftGetBase64Enc
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc)
{
return ZftGetBase64Enc
((const unsigned char*)APC_Origin, AL_Length, RR(ARR_CStringEnc));
}/*
template<typename TString> char* ZftGetBase64Enc
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc) */
template<typename TString> char* ZftGetBase64Enc
(const TString& ARR_CStringOri, TString& ARR_CStringEnc)
{
return ZftGetBase64Enc
(ARR_CStringOri.data(), ARR_CStringOri.size(), RR(ARR_CStringEnc));
}/*
template<typename TString> char* ZftGetBase64Enc
(const TString& ARR_CStringOri, TString& ARR_CStringEnc) */
template<typename TString> char* ZftGetBase64Dec
(const unsigned char* APC_Origin, long AL_Length,TString& ARR_CStringDec)
{
typedef unsigned char ZTypUChar;
ZTypUChar
VCA_TableBuff[256], *VPC_Out ,
*VPC_Pos , VCA_In[4] ,
VCA_Block[4] , VC_Temp ;
long i, VL_Count;
const int CI_Base64TableSize= 64;
const ZTypUChar* CPC_Base64Table =
(const ZTypUChar*)ZftGetBase64Table<char>() ;
memset(VCA_TableBuff, 0x80, 256);
for (i = 0; i < CI_Base64TableSize; i++)
{ VCA_TableBuff[CPC_Base64Table[i]] = i; }
VCA_TableBuff['=']=0; VL_Count=0; // '=' 는 61
for (i=0; i<AL_Length; i++)
{
if (VCA_TableBuff[APC_Origin[i]] != 0x80) VL_Count++;
}
/*///////////////////////*/
if (VL_Count % 4) return NULL;
ARR_CStringDec.resize(VL_Count,' ');
VPC_Pos = VPC_Out = (ZTypUChar*)ARR_CStringDec.c_str();
if (VPC_Out == NULL) return NULL;
VL_Count = 0;
for (i = 0; i < AL_Length; i++)
{
VC_Temp = VCA_TableBuff[APC_Origin[i]];
if (VC_Temp == 0x80) continue;
VCA_In[VL_Count] = APC_Origin[i];
VCA_Block[VL_Count] = VC_Temp ; VL_Count++;
if(VL_Count==4)
{
*VPC_Pos++ = (VCA_Block[0] << 2) | (VCA_Block[1] >> 4);
*VPC_Pos++ = (VCA_Block[1] << 4) | (VCA_Block[2] >> 2);
*VPC_Pos++ = (VCA_Block[2] << 6) | VCA_Block[3];
VL_Count = 0;
}/*
if(VL_Count==4)*/
}/*
for (i = 0; i < AL_Length; i++) */
if (VPC_Pos > VPC_Out)
{
if (VCA_In[2] == '=') VPC_Pos -= 2 ;
else if (VCA_In[3] == '=') VPC_Pos-- ;
}/*
if (VPC_Pos > VPC_Out)*/
ARR_CStringDec.resize(VPC_Pos - VPC_Out,' '); return (char*)VPC_Out;
}/*
template<typename TString> char* ZftGetBase64Dec
(const unsigned char* APC_Origin, long AL_Length,TString& ARR_CStringDec) */
template<typename TString> char* ZftGetBase64Dec
(const char* APC_Origin, long AL_Length,TString& ARR_CStringDec)
{
return ZftGetBase64Dec
((const unsigned char*)APC_Origin, AL_Length, RR(ARR_CStringDec));
}/*
template<typename TString> char* ZftGetBase64Dec
(const char* APC_Origin, long AL_Length, TString& ARR_CStringDec) */
template<typename TString> char* ZftGetBase64Dec
(const TString& ARR_CStringOri, TString& ARR_CStringDec)
{
return ZftGetBase64Dec
(ARR_CStringOri.data(), ARR_CStringOri.size(), RR(ARR_CStringDec));
}/*
template<typename TString> char* ZftGetBase64Dec
(const TString& ARR_CStringOri, TString& ARR_CStringDec) */
/*///////////////////////////////////////////////////////////////////////////////
■ 키이름과 키값의 쌍을 나타낼 때나 변수명과 변수값을 문자열로 표현할 때 Simple
Url(줄이면 SimUrl)라는 간단한 형식을 사용하자. 이 형식에서는 URL 형식과 비슷하
게 {변수명}={변수값} 의 쌍을 "&" 로 결합할 수 있도록, 데이타에 "&" 이 안들어가
'&' => %26
'%' => %25
'=' => %3D
으로 바꾸어 사용한다. 이 형식을 Simple URL 형식이라고 부르자.
■ -- 2009-05-22 18:05:00
///////////////////////////////////////////////////////////////////////////////*/
template<typename TString> TString& ZftGetSimUrlEnc
(const TString& AR_CStringOri, TString& ARR_CStringEnc)
{
if(&AR_CStringOri!=&ARR_CStringEnc)
{ ARR_CStringEnc = AR_CStringOri; }
ARR_CStringEnc.Replace("%","%25");
ARR_CStringEnc.Replace("=","%3D");
ARR_CStringEnc.Replace("&","%26");
return ARR_CStringEnc;
}/*
template<typename TString> TString& ZftGetSimUrlEnc
(const TString& AR_CStringOri, TString& ARR_CStringEnc) */
template<typename TString> TString& ZftGetSimUrlEnc(TString& ARR_CStringEnc)
{
ARR_CStringEnc.Replace("%","%25");
ARR_CStringEnc.Replace("=","%3D");
ARR_CStringEnc.Replace("&","%26");
return ARR_CStringEnc;
}/*
template<typename TString> TString& ZftGetSimUrlEnc(TString& ARR_CStringEnc) */
template<typename TString> TString& GetSimUrlDe
(const TString& AR_CStringOri, TString& ARR_CStringEnc)
{
ARR_CStringEnc=AR_CStringOri;
ARR_CStringEnc.Replace("%26","&");
ARR_CStringEnc.Replace("%3D","=");
ARR_CStringEnc.Replace("%25","%");
return ARR_CStringEnc;
}/*
template<typename TString> TString& ZftGetSimUrlDec
(const TString& AR_CStringOri, TString& ARR_CStringEnc) */
template<typename TString> TString& ZftGetSimUrlDec(TString& ARR_CStringOri)
{
ARR_CStringOri.Replace("%26","&");
ARR_CStringOri.Replace("%3D","=");
ARR_CStringOri.Replace("%25","%");
return ARR_CStringOri;
}/*
template<typename TString> TString& ZftGetSimUrlDec(TString& ARR_CStringOri) */
/*/////////////////////////////////////////////////////////////////////
■ 아주 간단한 암호화 복호화
1) 각 바이트 정수를 4 바이트의 문자열로 바꾼다.
2) 'A' 로 4 바이트 왼쪽 패딩한다.
3) 전체 문자열을 뒤집는다.
■ -- 2009-05-24 13:16:00
/////////////////////////////////////////////////////////////////////*/
template<typename TString> TString& ZftGetSimEnc
(const TString& AR_CStringOri, TString& ARR_CStringEnc)
{
typedef typename
TString::TypeChar TypeChar ;
const TypeChar* VP_Start
= AR_CStringOri.data() ;
TString VO_CStringBuff ;
for(int i=0;i<AR_CStringOri.size();++i)
{
VO_CStringBuff= int(*VP_Start++);
VO_CStringBuff.PadLeft(4, 'A' ); // 'A' 로 왼쪽 Padding
ARR_CStringEnc(VO_CStringBuff);
}/*
for(int i=0;i<AR_CStringOri.size();++i) */
return ARR_CStringEnc.Reverse();
}/*
template<typename TString> TString& ZftGetSimEnc
(const TString& AR_CStringOri, TString& ARR_CStringEnc) */
template<typename TString> TString& ZftGetSimDec
(const TString& AR_CStringOri, TString& ARR_CStringDec)
{
typedef typename TString::TypeChar TypeChar;
TString VO_CStringBuff ;
TString VO_CStringBuff4; // 4 바이트씩 자른 문자열 버퍼
VO_CStringBuff=AR_CStringOri;
VO_CStringBuff.Reverse() ;
TypeChar* VP_Start=VO_CStringBuff.data();
int VI_LoopCnt=VO_CStringBuff.size()/4;
for(int i=0; i<VI_LoopCnt; ++i)
{
(VO_CStringBuff4="")(VP_Start, 4); VP_Start+=4;
VO_CStringBuff4.Replace("A", "") ;
ARR_CStringDec(char(VO_CStringBuff4.GetInt()));
}/*
for(int i=0; i<AR_CStringOri.size(); ++i)*/
return ARR_CStringDec;
}/*
template<typename TString> TString& ZftGetSimDec
(const TString& AR_CStringOri, TString& ARR_CStringDec) */
static int ZfGetIntOfHex(char AC_Hex)
{
switch(AC_Hex)
{
case '0' : case '1' :
case '2' : case '3' :
case '4' : case '5' :
case '6' : case '7' :
case '8' : case '9' : return AC_Hex-'0';
case 'a' : case 'A' : return 10;
case 'b' : case 'B' : return 11;
case 'c' : case 'C' : return 12;
case 'd' : case 'D' : return 13;
case 'e' : case 'E' : return 14;
case 'f' : case 'F' : return 15;
};/*
switch(AC_Hex)*/
return -1;
}/*
static int ZfGetIntOfHex(char AC_Hex)*/
inline int ZfGetIntOfHex(char AC_Hex1, char AC_Hex2)
{
return ZfGetIntOfHex(AC_Hex1)*16 + ZfGetIntOfHex(AC_Hex2) ;
}/*
inline int ZfGetIntOfHex(char AC_Hex1, char AC_Hex2)*/
static char ZfGetHexCharOfInt(int AI_Integer)
{
switch(AI_Integer)
{
case 0 : case 1 :
case 2 : case 3 :
case 4 : case 5 :
case 6 : case 7 :
case 8 : case 9 : return AI_Integer+'0';
case 10 : return 'A';
case 11 : return 'B';
case 12 : return 'C';
case 13 : return 'D';
case 14 : return 'E';
case 15 : return 'F';
};/*
switch(AI_Integer)*/
return char(-1);
}/*
static char ZfGetHexCharOfInt(int AI_Integer)*/
inline void ZfGetHexCharOfInt(char AC_Int, char& AC_Hex1, char& AC_Hex2)
{
// AC_Int 의 값을 2 바이트의 16 진수 표현으로 바꾸어서 AC_Hex1, AC_Hex2 에 전달한다.
AC_Hex1= ZfGetHexCharOfInt(int((unsigned char)AC_Int)/16);
AC_Hex2= ZfGetHexCharOfInt(int((unsigned char)AC_Int)%16);
}/*
inline void ZfGetHexCharOfInt(char AC_Int, char& AC_Hex1, char& AC_Hex2)*/
template<typename TString> void ZftGetBinHexEnc
(const char* APC_Binary, int AI_Length, TString& ARR_CStringHex)
{
/* binary 포맷으로 되어 있는 데이타 APC_Binary 을 Hex 포맷으로 바꾼다.
Hex 포맷은 1 바이트를 2 바이트의 16 진수로 바꾼 것이다.
ex) binary 를 10FF780ABA 와 같은 Hex 로 바꾼다. */
if(AI_Length<1) return;
int VI_PrevBuffSize = ARR_CStringHex.size();
ARR_CStringHex.resize
(VI_PrevBuffSize+AI_Length*2, ' ');
int VI_LoopNo =AI_Length ; const ///////
char* VC_TmpChar1 =APC_Binary;
char* VC_TmpChar2 =
ARR_CStringHex.data() + VI_PrevBuffSize ;
for(int i=0;i<VI_LoopNo;++i)
{
ZfGetHexCharOfInt
( *VC_TmpChar1++, RR(*VC_TmpChar2), RR(*(VC_TmpChar2+1)) );
VC_TmpChar2 += 2;
}/*
for(int i=0;i<VI_LoopNo;++i)*/
}/*
template<typename TString> void ZftGetBinHexEnc
(const char* APC_Binary, int AI_Length, TString& ARR_CStringHex) */
template<typename TString> void ZftGetBinHexEnc
(const TString& AR_CStringBin, TString& ARR_CStringHex)
{
ZftGetBinHexEnc(AR_CStringBin.data(), AR_CStringBin.size(), RR(ARR_CStringHex));
}/*
template<typename TString> void ZftGetBinHexEnc
(const TString& AR_CStringBin, TString& ARR_CStringHex) */
template<typename TString> bool ZftGetBinHexDec
(const char* APC_HexData, int AI_Length, TString& ARR_CStringBin)
{
/* Hex 포맷으로 되어 있는 패킷 APC_HexData 을 binary 포맷으로 바꾼다.
Hex 포맷은 1 바이트를 2 바이트의 16 진수로 바꾼 것이다.
ex) 10FF780ABA 형식을 binary 로 바꾼다.
*/
int VI_LoopNo=AI_Length/2;
if(VI_LoopNo<1) return false;
int VI_PrevBuffSize=ARR_CStringBin.size();
ARR_CStringBin.resize(VI_PrevBuffSize+VI_LoopNo, ' ');
VI_LoopNo *= 2; const
char* VC_TmpChar1 = APC_HexData ;
char* VC_TmpChar2 =
ARR_CStringBin.data() + VI_PrevBuffSize ;
for(int i=0; i<VI_LoopNo; i+=2)
{
*VC_TmpChar2++ = (char)ZfGetIntOfHex(*VC_TmpChar1, *(VC_TmpChar1+1));
VC_TmpChar1 += 2;
}/*
for(int i=0; i<VI_LoopNo; i+=2)*/
return true;
}/*
template<typename TString> bool ZftGetBinHexDec
(const char* APC_HexData, int AI_Length, TString& ARR_CStringBin) */
template<typename TString> bool ZftGetBinHexDec
(const TString& AR_CStringHex, TString& ARR_CStringBin)
{
return ZftGetBinHexDec(AR_CStringHex.data(), AR_CStringHex.size(), RR(ARR_CStringBin));
}/*
template<typename TString> bool ZftGetBinHexDec
(const TString& AR_CStringHex, TString& ARR_CStringBin) */
template<typename TString, typename TIntArr> void ZftGetBinHexFormat
(
TString& ARR_CStringFormat ,
const TString& AR_CStringBin ,
const TIntArr& AR_ChunkSizeArr ,
int AI_Offset= 0 ,
const char* APC_Padd = ""
)
/*################################################################*/
{
/*///////////////////////////////////////////////////////////////
■ binary 표현 AR_CStringBin 에서 AI_Offset 번째 문자부터
'일정한 크기' 단위로 줄바꿈해서 (16 진수 포맷으로) 보여준다.
그 '일정한 크기' 를 CIntArr& AR_ChunkSizeArr 이 지정한다.
AR_ChunkSizeArr 의 원소가 3,4,5 로 되어있다면,
AR_CStringBin 의 AI_Offset 부터
3 개 바이트를 16 진수 포맷으로 출력한 다음 줄바꿈하고,
그 다음 4 개 바이트를 16 진수 포맷으로 출력한 다음 줄바꿈하고,
그 다음 5 개 바이트를 16 진수 포맷으로 출력한 다음 줄바꿈한다.
///////////////////////////////////////////////////////////////*/
int VI_ArrSize=AR_ChunkSizeArr.size(); int VI_LoopCnt=0;
if(AR_CStringBin.size()<=AI_Offset) return; /*#########*/
// 이전에는 VO_CStringBuff2 에 십진표기를 담았었다. 2009-12-18 21:22:00
TString VO_CStringBuff ;
//TString VO_CStringBuff2;
char VC_Char1=0; char VC_Char2=0;
const char* VPC_Binary = AR_CStringBin.data()+AI_Offset;
for(int i=1; i<=VI_ArrSize; ++i)
{
int VI_ChunkSize=AR_ChunkSizeArr[i-1];
VO_CStringBuff =APC_Padd; // 패딩을 한다.
//VO_CStringBuff2=" ☞ 십진표기(문자) : ";
for(int j=1; j<=VI_ChunkSize; ++j)
{
if((VI_LoopCnt++)+AI_Offset>=AR_CStringBin.size())
{
ARR_CStringFormat(" "); return;
}/*
if((VI_LoopCnt++)+AI_Offset>=AR_CStringBin.size())*/
ZfGetHexCharOfInt(*VPC_Binary,RR(VC_Char1),RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
/*////////////////////////////////////////////////////////////
if(*VPC_Binary==0)
VO_CStringBuff2("0(NULL) ");
else
VO_CStringBuff2(int(*VPC_Binary))("(")(*VPC_Binary)(") ");
//endif
////////////////////////////////////////////////////////////*/
++VPC_Binary;
}/*
for(int j=1; j<=VI_ChunkSize; ++j)*/
ARR_CStringFormat(VO_CStringBuff)/*(VO_CStringBuff2)*/;
if(VI_LoopCnt+AI_Offset>=AR_CStringBin.size())
{
ARR_CStringFormat(" "); return;
}/*
if(VI_LoopCnt+AI_Offset>=AR_CStringBin.size())*/
ARR_CStringFormat("\r\n");
}/*
for(int i=1; i<=VI_ArrSize; ++i)*/
if(VI_LoopCnt+AI_Offset<AR_CStringBin.size())
{
VO_CStringBuff = APC_Padd;
for(int i=VI_LoopCnt+AI_Offset; i<AR_CStringBin.size(); ++i)
{
ZfGetHexCharOfInt(*VPC_Binary++, RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
}/*
for(int i=VI_LoopCnt+AI_Offset; i<AR_CStringBin.size(); ++i)*/
ARR_CStringFormat(VO_CStringBuff);
}/*
if(VI_LoopCnt+AI_Offset<AR_CStringBin.size())*/
ARR_CStringFormat(" ");
}/*
template<typename TString, typename TIntArr> void ZftGetBinHexFormat
(
TString& ARR_CStringFormat ,
const TString& AR_CStringBin ,
const TIntArr& AR_ChunkSizeArr ,
int AI_Offset= 0 ,
const char* APC_Padd = ""
)
##################################################################*/
template<typename TString> void ZftGetBinHexFormat /*#############*/
(
TString& ARR_CStringFormat ,
const TString& AR_CStringBin ,
const int AIA_ChunkSizeArr[],
int AI_ArrSize ,
int AI_Offset= 0 ,
const char* APC_Padd = ""
)
/*################################################################*/
{
/*///////////////////////////////////////////////////////////////
■ binary 표현 AR_CStringBin 에서 AI_Offset 번째 문자부터
'일정한 크기' 단위로 줄바꿈해서 (16 진수 포맷으로) 보여준다.
그 '일정한 크기' 를 CIntArr& AR_ChunkSizeArr 이 지정한다.
AR_ChunkSizeArr 의 원소가 3,4,5 로 되어있다면,
AR_CStringBin 의 AI_Offset 부터
3 개 바이트를 16 진수 포맷으로 출력한 다음 줄바꿈하고,
그 다음 4 개 바이트를 16 진수 포맷으로 출력한 다음 줄바꿈하고,
그 다음 5 개 바이트를 16 진수 포맷으로 출력한 다음 줄바꿈한다.
///////////////////////////////////////////////////////////////*/
int VI_LoopCnt=0; if(AR_CStringBin.size()<=AI_Offset) return;
// 이전에는 VO_CStringBuff2 에 십진표기를 담았었다. 2009-12-18 21:22:00
TString VO_CStringBuff ;
//TString VO_CStringBuff2;
char VC_Char1=0; char VC_Char2=0;
const char* VPC_Binary=AR_CStringBin.data()+AI_Offset;
for(int i=1; i<=AI_ArrSize; ++i)
{
int VI_ChunkSize=AIA_ChunkSizeArr[i-1];
VO_CStringBuff =APC_Padd; // 패딩을 한다.
//VO_CStringBuff2=" ☞ 십진표기(문자) : ";
for(int j=1; j<=VI_ChunkSize; ++j)
{
if((VI_LoopCnt++)+AI_Offset>=AR_CStringBin.size())
{
ARR_CStringFormat(" "); return;
}/*
if((VI_LoopCnt++)+AI_Offset>=AR_CStringBin.size())*/
ZfGetHexCharOfInt(*VPC_Binary, RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
/*////////////////////////////////////////////////////////////
if(*VPC_Binary==0)
VO_CStringBuff2("0(NULL) ");
else
VO_CStringBuff2(int(*VPC_Binary))("(")(*VPC_Binary)(") ");
//else
////////////////////////////////////////////////////////////*/
++VPC_Binary;
}/*
for(int j=1; j<=VI_ChunkSize; ++j)*/
ARR_CStringFormat(VO_CStringBuff)/*(VO_CStringBuff2)*/;
if(VI_LoopCnt+AI_Offset>=AR_CStringBin.size())
{
ARR_CStringFormat(" "); return;
}/*
if(VI_LoopCnt+AI_Offset>=AR_CStringBin.size())*/
ARR_CStringFormat("\r\n");
}/*
for(int i=1; i<=AI_ArrSize; ++i)*/
if(VI_LoopCnt+AI_Offset<AR_CStringBin.size())
{
VO_CStringBuff=APC_Padd;
for(int i=VI_LoopCnt+AI_Offset; i<AR_CStringBin.size(); ++i)
{
ZfGetHexCharOfInt(*VPC_Binary++, RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
}/*
for(int i=VI_LoopCnt+AI_Offset; i<AR_CStringBin.size(); ++i)*/
ARR_CStringFormat(VO_CStringBuff);
}/*
if(VI_LoopCnt+AI_Offset<AR_CStringBin.size())*/
ARR_CStringFormat(" ");
}/*
template<typename TString> void ZftGetBinHexFormat #################
(
TString& ARR_CStringFormat ,
const TString& AR_CStringBin ,
const int AIA_ChunkSizeArr[],
int AI_ArrSize ,
int AI_Offset= 0 ,
const char* APC_Padd = ""
)
##################################################################*/
template<typename TString> void ZftGetBinHexFormat /*#############*/
(
TString& ARR_CStringFormat ,
const char* APC_DataBin ,
int AI_DataLen ,
const int AIA_ChunkSizeArr[],
int AI_ArrSize ,
int AI_Offset= 0 ,
const char* APC_Padd = ""
)
/*################################################################*/
{
int VI_LoopCnt=0; if(AI_DataLen<=AI_Offset) return;
TString VO_CStringBuff ;
//TString VO_CStringBuff2;
char VC_Char1 = 0; char VC_Char2=0;
const char* VPC_Binary= APC_DataBin+AI_Offset;
for(int i=1; i<=AI_ArrSize; ++i)
{
int VI_ChunkSize=AIA_ChunkSizeArr[i-1];
VO_CStringBuff =APC_Padd; // 패딩을 한다.
//VO_CStringBuff2=" ☞ 십진표기(문자) : ";
for(int j=1; j<=VI_ChunkSize; ++j)
{
if((VI_LoopCnt++)+AI_Offset>=AI_DataLen)
{
ARR_CStringFormat(" "); return;
}/*
if((VI_LoopCnt++)+AI_Offset>=AI_DataLen)*/
ZfGetHexCharOfInt(*VPC_Binary, RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
/*////////////////////////////////////////////////////////////
if(*VPC_Binary==0)
VO_CStringBuff2("0(NULL) ");
else
VO_CStringBuff2(int(*VPC_Binary))("(")(*VPC_Binary)(") ");
//else
////////////////////////////////////////////////////////////*/
++VPC_Binary;
}/*
for(int j=1; j<=VI_ChunkSize; ++j)*/
ARR_CStringFormat(VO_CStringBuff)/*(VO_CStringBuff2)*/;
if(VI_LoopCnt+AI_Offset>=AI_DataLen)
{
ARR_CStringFormat(" "); return;
}/*
if(VI_LoopCnt+AI_Offset>=AR_CStringBin.size())*/
ARR_CStringFormat("\r\n");
}/*
for(int i=1; i<=AI_ArrSize; ++i)*/
if(VI_LoopCnt+AI_Offset<AI_DataLen)
{
VO_CStringBuff = APC_Padd;
for(int i=VI_LoopCnt+AI_Offset; i<AI_DataLen; ++i)
{
ZfGetHexCharOfInt(*VPC_Binary++, RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
}/*
for(int i=VI_LoopCnt+AI_Offset; i<AI_DataLen; ++i)*/
ARR_CStringFormat(VO_CStringBuff);
}/*
if(VI_LoopCnt+AI_Offset<AI_DataLen)*/
ARR_CStringFormat(" ");
}/*
template<typename TString> void ZftGetBinHexFormat #################
(
TString& ARR_CStringFormat ,
const char* APC_DataBin ,
int AI_DataLen ,
const int AIA_ChunkSizeArr[],
int AI_ArrSize ,
int AI_Offset= 0 ,
const char* APC_Padd = ""
)
##################################################################*/
template
<typename TString, typename TIntArr, typename TTitleArr> //####
void ZftGetBinHexFormatEx
(
TString& ARR_CStringFormat ,
const TString& AR_CStringBin ,
const TIntArr& AR_ChunkSizeArr ,
const TTitleArr& AR_CStringTitleArr , // 각 줄바꿈 행 제목(문자열 object 배열)
int AI_Offset=0 ,
const char* APC_Padd =""
)
/*################################################################*/
{
/*///////////////////////////////////////////////////////////////
■ AR_ChunkSizeArr 가 지정하는 단위마다 줄바꿈 할 때마다,
AR_CStringTitleArr 이 지정하는 제목(문자열)을 함께 출력한다.
-- 2009-12-25 13:35:00
///////////////////////////////////////////////////////////////*/
int VI_ArrSize=AR_ChunkSizeArr.size(); int VI_LoopCnt=0;
if(AR_CStringBin.size()<=AI_Offset) return; /*########*/
// 이전에는 VO_CStringBuff2 에 십진표기를 담았었다. 2009-12-18 21:22:00
TString VO_CStringBuff ;
//TString VO_CStringBuff2;
char VC_Char1=0; char VC_Char2=0;
const char* VPC_Binary=AR_CStringBin.data()+AI_Offset;
for(int i=1;i<=VI_ArrSize;++i)
{
int VI_ChunkSize=AR_ChunkSizeArr[i-1];
VO_CStringBuff =APC_Padd; // 패딩을 한다.
//VO_CStringBuff2=" ☞ 십진표기(문자) : ";
if(AR_CStringTitleArr.size()>=i)
VO_CStringBuff(VO_CStringBuff)()(AR_CStringTitleArr[i-1]);
for(int j=1; j<=VI_ChunkSize; ++j)
{
if((VI_LoopCnt++)+AI_Offset>=AR_CStringBin.size())
{
ARR_CStringFormat(" "); return;
}/*
if((VI_LoopCnt++)+AI_Offset>=AR_CStringBin.size())*/
ZfGetHexCharOfInt(*VPC_Binary, RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
/*////////////////////////////////////////////////////////////
if(*VPC_Binary==0)
VO_CStringBuff2("0(NULL) ");
else
VO_CStringBuff2(int(*VPC_Binary))("(")(*VPC_Binary)(") ");
//else
////////////////////////////////////////////////////////////*/
++VPC_Binary;
}/*
for(int j=1; j<=VI_ChunkSize; ++j)*/
ARR_CStringFormat(VO_CStringBuff)/*(VO_CStringBuff2)*/;
if(VI_LoopCnt+AI_Offset>=AR_CStringBin.size())
{
ARR_CStringFormat(" "); return;
}/*
if(VI_LoopCnt+AI_Offset>=AR_CStringBin.size())*/
ARR_CStringFormat("\r\n");
}/*
for(int i=1; i<=VI_ArrSize; ++i)*/
if(VI_LoopCnt+AI_Offset < AR_CStringBin.size())
{
VO_CStringBuff=APC_Padd;
if(AR_CStringTitleArr.size()>VI_ArrSize)
VO_CStringBuff(VO_CStringBuff)()(AR_CStringTitleArr[VI_ArrSize]);
for(int i=VI_LoopCnt+AI_Offset; i<AR_CStringBin.size(); ++i)
{
ZfGetHexCharOfInt(
*VPC_Binary++,RR(VC_Char1), RR(VC_Char2) );
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
}/*
for(int i=VI_LoopCnt+AI_Offset; i<AR_CStringBin.size(); ++i)*/
ARR_CStringFormat(VO_CStringBuff);
}/*
if(VI_LoopCnt+AI_Offset < AR_CStringBin.size())*/
ARR_CStringFormat(" ");
}/*
template
<typename TString, typename TIntArr, typename TTitleArr> #######
void ZftGetBinHexFormatEx
(
TString& ARR_CStringFormat ,
const TString& AR_CStringBin ,
const TIntArr& AR_ChunkSizeArr ,
const TTitleArr& AR_CStringTitleArr ,
int AI_Offset=0 ,
const char* APC_Padd =""
)
##################################################################*/
template<typename TString> void ZftGetBinHexFormatEx( /*##########*/
TString& ARR_CStringFormat ,
const char* APC_DataBin ,
int AI_DataLen ,
const int AIA_ChunkSizeArr[] ,
int AI_ArrSize ,
const char* ASzA_TitleArr[] ,
int AI_TitleArrSize ,
int AI_Offset=0 ,
const char* APC_Padd=""
/*#########*/ ) /*################################################*/
{
int VI_LoopCnt=0; if(AI_DataLen<=AI_Offset) return;
TString VO_CStringBuff ;
//TString VO_CStringBuff2;
char VC_Char1=0; char VC_Char2=0;
const char* VPC_Binary=APC_DataBin+AI_Offset;
for(int i=1; i<=AI_ArrSize; ++i)
{
int VI_ChunkSize=AIA_ChunkSizeArr[i-1];
VO_CStringBuff =APC_Padd; // 패딩을 한다.
//VO_CStringBuff2=" ☞ 십진표기(문자) : ";
if(AI_TitleArrSize>=i)
VO_CStringBuff(ASzA_TitleArr[i-1]);
for(int j=1; j<=VI_ChunkSize; ++j)
{
if((VI_LoopCnt++)+AI_Offset>=AI_DataLen)
{
ARR_CStringFormat(" "); return;
}
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
ZfGetHexCharOfInt(*VPC_Binary,RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
/*////////////////////////////////////////////////////////////
if(*VPC_Binary==0)
VO_CStringBuff2("0(NULL) ");
else
VO_CStringBuff2(int(*VPC_Binary))("(")(*VPC_Binary)(") ");
//endif
////////////////////////////////////////////////////////////*/
++VPC_Binary;
}/*
for(int j=1; j<=VI_ChunkSize; ++j)*/
ARR_CStringFormat(VO_CStringBuff)/*(VO_CStringBuff2)*/;
if(VI_LoopCnt+AI_Offset>=AI_DataLen)
{
ARR_CStringFormat(" "); return;
}
/*////////////////////////////////*/
ARR_CStringFormat("\r\n");
}/*
for(int i=1; i<=AI_ArrSize; ++i)*/
if(VI_LoopCnt+AI_Offset < AI_DataLen)
{
VO_CStringBuff=APC_Padd;
if(AI_TitleArrSize>AI_ArrSize)
VO_CStringBuff(ASzA_TitleArr[AI_ArrSize]);
for(int i=VI_LoopCnt+AI_Offset; i<AI_DataLen; ++i)
{
ZfGetHexCharOfInt
(*VPC_Binary++, RR(VC_Char1), RR(VC_Char2));
VO_CStringBuff(VC_Char1)(VC_Char2)(" ");
}/*
for(int i=VI_LoopCnt+AI_Offset; i<AI_DataLen; ++i)*/
ARR_CStringFormat(VO_CStringBuff);
}/*
if(VI_LoopCnt+AI_Offset < AI_DataLen)*/
ARR_CStringFormat(" ");
}/*
template<typename TString> void ZftGetBinHexFormatEx( #############
TString& ARR_CStringFormat ,
const char* APC_DataBin ,
int AI_DataLen ,
const int AIA_ChunkSizeArr[] ,
int AI_ArrSize ,
const char* ASzA_TitleArr[] ,
int AI_TitleArrSize ,
int AI_Offset=0 ,
const char* APC_Padd=""
############# ) #################################################*/
class ZCBase64
{
public:
template<typename TString> static void Encode
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc)
{
ZNsMain::ZNsEnc::ZftGetBase64Enc((const unsigned char*)APC_Origin, AL_Length, RR(ARR_CStringEnc));
}/*
template<typename TString> static void Encode
(const char* APC_Origin, long AL_Length, TString& ARR_CStringEnc) */
template<typename TString> static void Encode
(const TString& ARR_CStringOri, TString& ARR_CStringEnc)
{
Encode(ARR_CStringOri.data(), ARR_CStringOri.size(), RR(ARR_CStringEnc));
}/*
template<typename TString> static void Encode
(const TString& ARR_CStringOri, TString& ARR_CStringEnc) */
template<typename TString> static void Decode
(const char* APC_Origin, long AL_Length, TString& ARR_CStringDec)
{
ZNsMain::ZNsEnc::ZftGetBase64Dec
((const unsigned char*)APC_Origin, AL_Length, RR(ARR_CStringDec));
}/*
template<typename TString> static void Decode
(const char* APC_Origin, long AL_Length, TString& ARR_CStringDec) */
template<typename TString> static void Decode
(const TString& ARR_CStringOri, TString& ARR_CStringDec)
{
Decode(ARR_CStringOri.data(), ARR_CStringOri.size(), RR(ARR_CStringDec));
}/*
template<typename TString> static void Decode
(const TString& ARR_CStringOri, TString& ARR_CStringDec) */
public:
};/*
class ZCBase64*/
class ZCSha1
{
public :
enum EResult
{
EResult_Success ,
EResult_TooLong , /* input data too long */
EResult_Error /* called Input after Result */
};/*
enum EResult*/
public :
enum{ ESHA1HashSize = 20 } ;
public :
typedef uint8_t
UInt8Digest[ESHA1HashSize];
private:
struct StContext
{
uint32_t muia_IntermedHash[ESHA1HashSize/4]; /* Message Digest Intermediate Hash */
uint32_t mui_LengthLow ; /* Message length in bits */
uint32_t mui_LengthHigh ; /* Message length in bits */
int16_t mi_MsgBlockIndex ; /* Index into message block array, 최소 16 bit 이상의 크기 정수 */
uint8_t muca_MsgBlock[64] ; /* 512-bit message blocks */
int mb_IsComputed ; /* Is the digest computed? */
EResult me_EResult ; /* Is the message digest corrupted? */
};/*
struct StContext*/
private:
#define SHA1CircularShift(bits,word) \
(((word) << (bits)) | ((word) >> (32-(bits))))
private:
StContext mo_StContext;
UInt8Digest muca_Digest ;
private:
void InitContext()
{
mo_StContext.mui_LengthLow = 0 ;
mo_StContext.mui_LengthHigh = 0 ;
mo_StContext.mi_MsgBlockIndex = 0 ;
mo_StContext.muia_IntermedHash[0] = 0x67452301;
mo_StContext.muia_IntermedHash[1] = 0xEFCDAB89;
mo_StContext.muia_IntermedHash[2] = 0x98BADCFE;
mo_StContext.muia_IntermedHash[3] = 0x10325476;
mo_StContext.muia_IntermedHash[4] = 0xC3D2E1F0;
mo_StContext.mb_IsComputed = false ;
mo_StContext.me_EResult = EResult_Success;
}/*
void InitContext()*/
void HandleMsgBlock()
{
const uint32_t K[] = /* Constants defined in SHA-1 */
{
0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6
};/*
const uint32_t K[] = */
int t ; /* Loop counter */
uint32_t temp; /* Temporary word value */
uint32_t W[80]; /* Word sequence */
uint32_t A, B, C, D, E; /* Word buffers */
/*
* Initialize the first 16 words in the array W
*/
for(t = 0; t < 16; t++)
{
W[t] = mo_StContext.muca_MsgBlock[t * 4 ] << 24;
W[t] |= mo_StContext.muca_MsgBlock[t * 4 + 1] << 16;
W[t] |= mo_StContext.muca_MsgBlock[t * 4 + 2] << 8 ;
W[t] |= mo_StContext.muca_MsgBlock[t * 4 + 3];
}/*
for(t = 0; t < 16; t++)*/
for(t = 16; t < 80; t++)
{
W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
}/*
for(t = 16; t < 80; t++)*/
A = mo_StContext.muia_IntermedHash[0];
B = mo_StContext.muia_IntermedHash[1];
C = mo_StContext.muia_IntermedHash[2];
D = mo_StContext.muia_IntermedHash[3];
E = mo_StContext.muia_IntermedHash[4];
for(t = 0; t < 20; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | ((~B) & D)) + E + W[t] + K[0];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}/*
for(t = 0; t < 20; t++)*/
for(t = 20; t < 40; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}/*
for(t = 20; t < 40; t++)*/
for(t = 40; t < 60; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}/*
for(t = 40; t < 60; t++)*/
for(t = 60; t < 80; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}/*
for(t = 60; t < 80; t++)*/
mo_StContext.muia_IntermedHash[0] += A;
mo_StContext.muia_IntermedHash[1] += B;
mo_StContext.muia_IntermedHash[2] += C;
mo_StContext.muia_IntermedHash[3] += D;
mo_StContext.muia_IntermedHash[4] += E;
mo_StContext.mi_MsgBlockIndex = 0;
}/*
void HandleMsgBlock()*/
void PadMessage()
{
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second
* block.
*/
if(mo_StContext.mi_MsgBlockIndex > 55)
{
mo_StContext.muca_MsgBlock[mo_StContext.mi_MsgBlockIndex++] = 0x80;
while(mo_StContext.mi_MsgBlockIndex < 64)
mo_StContext.muca_MsgBlock[mo_StContext.mi_MsgBlockIndex++] = 0;
HandleMsgBlock();
while(mo_StContext.mi_MsgBlockIndex < 56)
mo_StContext.muca_MsgBlock[mo_StContext.mi_MsgBlockIndex++] = 0;
}
else // mo_StContext.mi_MsgBlockIndex <= 55
{
mo_StContext.muca_MsgBlock[mo_StContext.mi_MsgBlockIndex++] = 0x80;
while(mo_StContext.mi_MsgBlockIndex < 56)
mo_StContext.muca_MsgBlock[mo_StContext.mi_MsgBlockIndex++] = 0;
}/*
else // mo_StContext.mi_MsgBlockIndex <= 55 */
/*
* Store the message length as the last 8 octets
*/
mo_StContext.muca_MsgBlock[56] = mo_StContext.mui_LengthHigh >> 24;
mo_StContext.muca_MsgBlock[57] = mo_StContext.mui_LengthHigh >> 16;
mo_StContext.muca_MsgBlock[58] = mo_StContext.mui_LengthHigh >> 8 ;
mo_StContext.muca_MsgBlock[59] = mo_StContext.mui_LengthHigh ;
mo_StContext.muca_MsgBlock[60] = mo_StContext.mui_LengthLow >> 24;
mo_StContext.muca_MsgBlock[61] = mo_StContext.mui_LengthLow >> 16;
mo_StContext.muca_MsgBlock[62] = mo_StContext.mui_LengthLow >> 8 ;
mo_StContext.muca_MsgBlock[63] = mo_StContext.mui_LengthLow ;
HandleMsgBlock();
}/*
void PadMessage()*/
void Calculate()
{
if(mo_StContext.me_EResult!=EResult_Success) return;
int i;
if(!mo_StContext.mb_IsComputed)
{
PadMessage();
for(i=0; i<64; ++i)
{
/* message may be sensitive, clear it out */
mo_StContext.muca_MsgBlock[i] = 0;
}/*
for(i=0; i<64; ++i)*/
mo_StContext.mui_LengthLow = 0; /* and clear length */
mo_StContext.mui_LengthHigh= 0;
mo_StContext.mb_IsComputed = true;
}/*
if(!mo_StContext.mb_IsComputed)*/
for(i = 0; i < ESHA1HashSize; ++i)
{
muca_Digest[i] =
mo_StContext.muia_IntermedHash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) );
}/*
for(i = 0; i < ESHA1HashSize; ++i)*/
}/*
void Calculate()*/
/*private:*/
public :
void Encode(const uint8_t* APUC_Message, int AI_Length)
{
InitContext(); if (AI_Length<1) return;
while(AI_Length-->0 && mo_StContext.me_EResult==EResult_Success)
{
mo_StContext.muca_MsgBlock[mo_StContext.mi_MsgBlockIndex++] =
(*APUC_Message & 0xFF);
mo_StContext.mui_LengthLow += 8;
if(mo_StContext.mui_LengthLow == 0)
{
mo_StContext.mui_LengthHigh++;
if (mo_StContext.mui_LengthHigh == 0)
mo_StContext.me_EResult = EResult_TooLong;
}/*
if(mo_StContext.mui_LengthLow == 0)*/
if(mo_StContext.mi_MsgBlockIndex == 64)
HandleMsgBlock();
APUC_Message++;
}/*
while(AI_Length-->0 && mo_StContext.me_EResult==EResult_Success)*/
Calculate(); /////////////////////////////////////////////////////
}/*
void Encode(const uint8_t* APUC_Message, int AI_Length)*/
void Encode(const char* APC_Message, int AI_Length)
{
Encode((const uint8_t*)APC_Message, AI_Length);
}/*
void Encode(const char* APC_Message, int AI_Length)*/
void Encode(const char* APC_Message)
{
Encode(APC_Message, ZNsMain::ZftLength(APC_Message));
}/*
void Encode(const char* APC_Message)*/
template<typename TStringData> void EncodeCStr(TStringData& AR_CStringOri)
{
Encode(AR_CStringOri.data(), AR_CStringOri.size());
}/*
template<typename TStringData> void EncodeCStr(TStringData& AR_CStringOri)*/
UInt8Digest& GetDigest(){return muca_Digest;}
template<typename TStringData> void GetDigestBin(TStringData& ARR_CStringBin)
{
ARR_CStringBin((const char*)muca_Digest, ESHA1HashSize);
}/*
template<typename TStringData> void GetDigestBin(TStringData& ARR_CStringBin)*/
template<typename TStringData> void GetDigestHex(TStringData& ARR_CStringHex)
{
ARR_CStringHex.resize(ESHA1HashSize*2);
unsigned char* VPUC_Digest=muca_Digest;
for(int i=0;i<ESHA1HashSize;++i)
{
::sprintf(ARR_CStringHex.data()+i*2, "%02X", *VPUC_Digest++);
}/*
for(int i=0;i<ESHA1HashSize;++i)*/
}/*
template<typename TStringData> void GetDigestHex(TStringData& ARR_CStringHex)*/
#undef SHA1CircularShift
public :
};/*
class ZCSha1*/
}/*
namespace ZNsEnc*/
}/*
namespace ZNsMain */
/*/////////////////////////////////////////////////////////////////////////////////////////
■ namespace ZNsEnc 있는 암호 복화화 함수를 클래스가 아닌 함수로 구현되는 알고리즘이 있다면,
그 알고리즘을 MyCode 라고 부른다고 할 때,
인코딩하는 함수는 GetMyCodeEnc() 하 하고, 디코딩하는 함수는 GetMyCodeDec() 하 하자.
/////////////////////////////////////////////////////////////////////////////////////////*/
#endif //__ZCPPMAIN__ZMAINENC_H__