www.gusucode.com > Base64的编解码方法JavaScript源码程序 > Base64的编解码方法/SeeBase64/SeeBase64Dlg.cpp
// SeeBase64Dlg.cpp : 实现文件 // #include "stdafx.h" #include "SeeBase64.h" #include "SeeBase64Dlg.h" #include ".\seebase64dlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialog { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CSeeBase64Dlg 对话框 CSeeBase64Dlg::CSeeBase64Dlg(CWnd* pParent /*=NULL*/) : CDialog(CSeeBase64Dlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CSeeBase64Dlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_TAB1, m_MainTab); } BEGIN_MESSAGE_MAP(CSeeBase64Dlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTabSelChange) ON_BN_CLICKED(IDC_BTN_DCD, OnBnClickedBtnDcd) ON_WM_SHOWWINDOW() ON_BN_CLICKED(IDC_BTN_ECD, OnBnClickedBtnEcd) END_MESSAGE_MAP() // CSeeBase64Dlg 消息处理程序 BOOL CSeeBase64Dlg::OnInitDialog() { CDialog::OnInitDialog(); // 将\“关于...\”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 InitUiTab(); AfxOleInit(); return TRUE; // 除非设置了控件的焦点,否则返回 TRUE } void CSeeBase64Dlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CSeeBase64Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标显示。 HCURSOR CSeeBase64Dlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CSeeBase64Dlg::InitUiTab() { m_TabDlgText.Create(IDD_DIAG_TEXT, this); m_TabDlgFile.Create(IDD_DIAG_FILE, this); CRect TabRc; CRect DlgRc; m_MainTab.GetWindowRect(&TabRc); ScreenToClient(&TabRc); TabRc.left += 10; TabRc.top += 40; TabRc.bottom -= 10; TabRc.right -= 10; m_TabDlgText.MoveWindow(&TabRc, TRUE); m_TabDlgFile.MoveWindow(&TabRc, TRUE); m_MainTab.InsertItem(0, "Text"); m_MainTab.InsertItem(1, "File"); ShowTab(0); } void CSeeBase64Dlg::ShowTab(int idx) { if (idx == 0) { m_TabDlgText.ShowWindow(SW_SHOW); m_TabDlgFile.ShowWindow(SW_HIDE); CWnd * pwnd = m_TabDlgText.GetDlgItem(IDC_EDIT_BASE64); pwnd->SetFocus(); } else { m_TabDlgText.ShowWindow(SW_HIDE); m_TabDlgFile.ShowWindow(SW_SHOW); CWnd * pwnd = m_TabDlgFile.GetDlgItem(IDC_EDIT_BASE64_FILE); pwnd->SetFocus(); } } void CSeeBase64Dlg::OnTabSelChange( NMHDR * pNotifyStruct, LRESULT * result ) { int idx = m_MainTab.GetCurSel(); ShowTab(idx); } void CSeeBase64Dlg::OnBnClickedBtnDcd() { // TODO: 在此添加控件通知处理程序代码 int idx = m_MainTab.GetCurSel(); if (idx == 0) { // decode base64 string OnDecodeBase64StringBtn(); } else { // decode base64 file OnDecodeBase64FileBtn(); } } void CSeeBase64Dlg::OnDecodeBase64StringBtn() { m_TabDlgText.UpdateData(TRUE); DecodeBase64(m_TabDlgText.m_strInput.GetBuffer(1024), m_TabDlgText.m_strOutput.GetBuffer(1024)); m_TabDlgText.m_strInput.ReleaseBuffer(); m_TabDlgText.m_strOutput.ReleaseBuffer(); m_TabDlgText.UpdateData(FALSE); } #define DCD_ONCE_LEN 400*1024 #define CDC_ONCE_LEN 300*1024 void CSeeBase64Dlg::OnDecodeBase64FileBtn() { CFile Base64File; CFile NativeFile; if (FALSE == Base64File.Open(m_TabDlgFile.m_strBase64File, CFile::modeRead)) { AfxMessageBox("Open Base64 File Failed!"); return; } if (FALSE == NativeFile.Open(m_TabDlgFile.m_strNativeFile, CFile::modeReadWrite)) { Base64File.Close(); AfxMessageBox("Open Native File Failed!"); return; } char * pszInput = new char[DCD_ONCE_LEN+1]; char * pszOutput = new char[CDC_ONCE_LEN+1]; memset(pszInput, 0x00, DCD_ONCE_LEN+1); memset(pszOutput, 0x00, CDC_ONCE_LEN+1); while (1) { int iLen = 0; iLen = Base64File.Read(pszInput, DCD_ONCE_LEN); int iDstLen = DecodeBase64(pszInput, pszOutput); NativeFile.Write(pszOutput, iDstLen); if (iLen < DCD_ONCE_LEN) { break; } } delete [] pszInput; delete [] pszOutput; Base64File.Close(); NativeFile.Close(); AfxMessageBox("Decode OK!"); } const BYTE Base64IdxTab[128] = { 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,62, 255,255,255,63, 52,53,54,55, 56,57,58,59, 60,61,255,255, 255,255,255,255, 255,0,1,2, 3,4,5,6, 7,8,9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,255, 255,255,255,255, 255,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,255, 255,255,255,255 }; #define BVal(x) Base64IdxTab[x] int CSeeBase64Dlg::DecodeBase64(char * pInput, char * pOutput) { int i = 0; int iCnt = 0; int iSrcLen = (int)strlen(pInput); char * p = pOutput; for (i=0; i<iSrcLen; i++) { if (pInput[i] > 127) continue; if (pInput[i] == '=') return p-pOutput+1; BYTE a = BVal(pInput[i]); if (a == 255) continue; switch (iCnt) { case 0: { *p = a << 2; iCnt++; } break; case 1: { *p++ |= a >> 4; *p = a << 4; iCnt++; } break; case 2: { *p++ |= a >> 2; *p = a << 6; iCnt++; } break; case 3: { *p++ |= a; iCnt = 0; } break; } } *p = 0x00; return p-pOutput; } void CSeeBase64Dlg::OnShowWindow(BOOL bShow,UINT nStatus) { CWnd * pwnd = m_TabDlgText.GetDlgItem(IDC_EDIT_BASE64); pwnd->SetFocus(); } void CSeeBase64Dlg::OnBnClickedBtnEcd() { int idx = m_MainTab.GetCurSel(); if (idx == 0) { // decode base64 string OnEncodeBase64StringBtn(); } else { // decode base64 file OnEncodeBase64FileBtn(); } } void CSeeBase64Dlg::OnEncodeBase64StringBtn() { m_TabDlgText.UpdateData(TRUE); EncodeBase64(m_TabDlgText.m_strOutput.GetBuffer(1024), m_TabDlgText.m_strInput.GetBuffer(1024)); m_TabDlgText.m_strInput.ReleaseBuffer(); m_TabDlgText.m_strOutput.ReleaseBuffer(); m_TabDlgText.UpdateData(FALSE); } void CSeeBase64Dlg::OnEncodeBase64FileBtn() { CFile Base64File; CFile NativeFile; if (FALSE == Base64File.Open(m_TabDlgFile.m_strBase64File, CFile::modeRead)) { AfxMessageBox("Open Base64 File Failed!"); return; } if (FALSE == NativeFile.Open(m_TabDlgFile.m_strNativeFile, CFile::modeReadWrite)) { Base64File.Close(); AfxMessageBox("Open Native File Failed!"); return; } char * pszInput = new char[CDC_ONCE_LEN+1]; char * pszOutput = new char[DCD_ONCE_LEN+1]; memset(pszInput, 0x00, CDC_ONCE_LEN+1); memset(pszOutput, 0x00, DCD_ONCE_LEN+1); while (1) { int iLen = 0; iLen = NativeFile.Read(pszInput, CDC_ONCE_LEN); int iDstLen = EncodeBase64(pszInput, pszOutput); Base64File.Write(pszOutput, iDstLen); if (iLen < CDC_ONCE_LEN) { break; } } Base64File.Close(); NativeFile.Close(); delete [] pszInput; delete [] pszOutput; AfxMessageBox("Encode OK!"); } const BYTE Base64ValTab[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; #define AVal(x) Base64ValTab[x] int CSeeBase64Dlg::EncodeBase64(char * pInput, char * pOutput) { int i = 0; int loop = 0; int remain = 0; int iDstLen = 0; int iSrcLen = (int)strlen(pInput); loop = iSrcLen/3; remain = iSrcLen%3; // also can encode native char one by one as decode method // but because all of char in native string is to be encoded so encode 3-chars one time is easier. for (i=0; i<loop; i++) { BYTE a1 = (pInput[i*3] >> 2); BYTE a2 = ( ((pInput[i*3] & 0x03) << 4) | (pInput[i*3+1] >> 4) ); BYTE a3 = ( ((pInput[i*3+1] & 0x0F) << 2) | ((pInput[i*3+2] & 0xC0) >> 6) ); BYTE a4 = (pInput[i*3+2] & 0x3F); pOutput[i*4] = AVal(a1); pOutput[i*4+1] = AVal(a2); pOutput[i*4+2] = AVal(a3); pOutput[i*4+3] = AVal(a4); } iDstLen = i*4; if (remain == 1) { // should pad two equal sign i = iSrcLen-1; BYTE a1 = (pInput[i] >> 2); BYTE a2 = ((pInput[i] & 0x03) << 4); pOutput[iDstLen++] = AVal(a1); pOutput[iDstLen++] = AVal(a2); pOutput[iDstLen++] = '='; pOutput[iDstLen++] = '='; pOutput[iDstLen] = 0x00; } else if (remain == 2) { // should pad one equal sign i = iSrcLen-2; BYTE a1 = (pInput[i] >> 2); BYTE a2 = ( ((pInput[i] & 0x03) << 4) | (pInput[i+1] >> 4)); BYTE a3 = ( (pInput[i+1] & 0x0F) << 2); pOutput[iDstLen++] = AVal(a1); pOutput[iDstLen++] = AVal(a2); pOutput[iDstLen++] = AVal(a3); pOutput[iDstLen++] = '='; pOutput[iDstLen] = 0x00; } else { // just division by 3 pOutput[iDstLen] = 0x00; } return iDstLen; }