📄 cyoencode.cpp
字号:
//////////////////////////////////////////////////////////////////////
//
// CyoEncode.cpp
//
// Developed by Graham Bull for Cyotec Systems Limited.
// http://www.cyotec.com
//
// Copyright (c) 2004 by Cyotec Systems Limited. All Rights Reserved.
//
// This source code may be used, modified, compiled, duplicated, and/or
// distributed without restriction provided this copyright notice remains intact.
// Cyotec Systems Limited and/or its employees cannot be held responsible for any
// direct or indirect damage or loss of any kind that may result from using this
// code, and provides no warranty, guarantee, or support.
//
// Associated Files
// - CyoEncode.h
// - CyoDecode.h
// - CyoDecode.cpp
//
// History
// - September 22, 2004 - Created
// - November 04, 2004 - Not strictly ANSI compatible!
//
//////////////////////////////////////////////////////////////////////
#include "CyoEncode.h"
#include <stdexcept> //for std::runtime_error
#include <assert.h> //for assert()
typedef unsigned char BYTE, *LPBYTE;
typedef unsigned long DWORD;
typedef const char* LPCSTR;
////////////////////////////////////////
// Constants
namespace CyoEncode
{
DWORD BASE16_INPUT = 1;
DWORD BASE16_OUTPUT = 2;
LPCSTR BASE16_TABLE = "0123456789ABCDEF";
DWORD BASE32_INPUT = 5;
DWORD BASE32_OUTPUT = 8;
LPCSTR BASE32_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=";
DWORD BASE64_INPUT = 3;
DWORD BASE64_OUTPUT = 4;
LPCSTR BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const char* c_pszErrorInvalidParameter = "Invalid parameter";
}
////////////////////////////////////////
// Base16 Encoding
unsigned long CyoEncode::Base16EncodeGetLength( unsigned long size )
{
// output 2 bytes for every 1 input:
// 1
// 1 = ----1111 = 1111----
// 2 = ----1111 = ----1111
return (((size + BASE16_INPUT - 1) / BASE16_INPUT) * BASE16_OUTPUT);
}
unsigned long CyoEncode::Base16Encode( void* dest, const void* src, unsigned long size )
{
if (!dest || !src)
throw std::runtime_error( c_pszErrorInvalidParameter );
///
LPBYTE pSrc = (LPBYTE)src;
LPBYTE pDest = (LPBYTE)dest;
DWORD dwSrcSize = size;
DWORD dwDestSize = 0;
while (dwSrcSize >= 1)
{
// 1 input...
BYTE ch = *pSrc++;
dwSrcSize -= BASE16_INPUT; //1
// 2 outputs...
*pDest++ = BASE16_TABLE[ (ch & 0xf0) >> 4 ];
*pDest++ = BASE16_TABLE[ (ch & 0x0f) ];
dwDestSize += BASE16_OUTPUT; //2
}
return dwDestSize;
}
////////////////////////////////////////
// Base32 Encoding
unsigned long CyoEncode::Base32EncodeGetLength( unsigned long size )
{
// output 8 bytes for every 5 input:
// 1 2 3 4 5
// 1 = ---11111 = 11111---
// 2 = ---111XX = -----111 XX------
// 3 = ---11111 = --11111-
// 4 = ---1XXXX = -------1 XXXX----
// 5 = ---1111X = ----1111 X-------
// 6 = ---11111 = -11111--
// 7 = ---11XXX = ------11 XXX-----
// 8 = ---11111 = ---11111
return (((size + BASE32_INPUT - 1) / BASE32_INPUT) * BASE32_OUTPUT);
}
unsigned long CyoEncode::Base32Encode( void* dest, const void* src, unsigned long size )
{
if (!dest || !src)
throw std::runtime_error( c_pszErrorInvalidParameter );
///
LPBYTE pSrc = (LPBYTE)src;
LPBYTE pDest = (LPBYTE)dest;
DWORD dwSrcSize = size;
DWORD dwDestSize = 0;
while (dwSrcSize >= 1)
{
unsigned long dwBlockSize = __min( dwSrcSize, BASE32_INPUT );
assert( 1 <= dwBlockSize && dwBlockSize <= BASE32_INPUT );
// Encode inputs...
BYTE n1, n2 = 0, n3 = 0, n4 = 0, n5 = 0, n6 = 0, n7 = 0, n8 = 0;
switch (dwBlockSize)
{
case 5:
n8 = (pSrc[ 4 ] & 0x1f);
n7 = ((pSrc[ 4 ] & 0xe0) >> 5);
case 4:
n7 |= ((pSrc[ 3 ] & 0x03) << 3);
n6 = ((pSrc[ 3 ] & 0x7c) >> 2);
n5 = ((pSrc[ 3 ] & 0x80) >> 7);
case 3:
n5 |= ((pSrc[ 2 ] & 0x0f) << 1);
n4 = ((pSrc[ 2 ] & 0xf0) >> 4);
case 2:
n4 |= ((pSrc[ 1 ] & 0x01) << 4);
n3 = ((pSrc[ 1 ] & 0x3e) >> 1);
n2 = ((pSrc[ 1 ] & 0xc0) >> 6);
case 1:
n2 |= ((pSrc[ 0 ] & 0x07) << 2);
n1 = ((pSrc[ 0 ] & 0xf8) >> 3);
break;
default:
assert( false );
}
pSrc += dwBlockSize;
dwSrcSize -= dwBlockSize;
// Validate...
assert( 0 <= n1 && n1 <= 31 );
assert( 0 <= n2 && n2 <= 31 );
assert( 0 <= n3 && n3 <= 31 );
assert( 0 <= n4 && n4 <= 31 );
assert( 0 <= n5 && n5 <= 31 );
assert( 0 <= n6 && n6 <= 31 );
assert( 0 <= n7 && n7 <= 31 );
assert( 0 <= n8 && n8 <= 31 );
// Padding...
switch (dwBlockSize)
{
case 1: n3 = n4 = 32;
case 2: n5 = 32;
case 3: n6 = n7 = 32;
case 4: n8 = 32;
case 5:
break;
default:
assert( false );
}
// 8 outputs...
*pDest++ = BASE32_TABLE[ n1 ];
*pDest++ = BASE32_TABLE[ n2 ];
*pDest++ = BASE32_TABLE[ n3 ];
*pDest++ = BASE32_TABLE[ n4 ];
*pDest++ = BASE32_TABLE[ n5 ];
*pDest++ = BASE32_TABLE[ n6 ];
*pDest++ = BASE32_TABLE[ n7 ];
*pDest++ = BASE32_TABLE[ n8 ];
dwDestSize += BASE32_OUTPUT; //8
}
return dwDestSize;
}
////////////////////////////////////////
// Base64 Encoding
unsigned long CyoEncode::Base64EncodeGetLength( unsigned long size )
{
// output 4 bytes for every 3 input:
// 1 2 3
// 1 = --111111 = 111111--
// 2 = --11XXXX = ------11 XXXX----
// 3 = --1111XX = ----1111 XX------
// 4 = --111111 = --111111
return (((size + BASE64_INPUT - 1) / BASE64_INPUT) * BASE64_OUTPUT);
}
unsigned long CyoEncode::Base64Encode( void* dest, const void* src, unsigned long size )
{
if (!dest || !src)
throw std::runtime_error( c_pszErrorInvalidParameter );
///
LPBYTE pSrc = (LPBYTE)src;
LPBYTE pDest = (LPBYTE)dest;
DWORD dwSrcSize = size;
DWORD dwDestSize = 0;
while (dwSrcSize >= 1)
{
unsigned long dwBlockSize = __min( dwSrcSize, BASE64_INPUT );
assert( 1 <= dwBlockSize && dwBlockSize <= BASE64_INPUT );
// Encode inputs...
BYTE n1, n2 = 0, n3 = 0, n4 = 0;
switch (dwBlockSize)
{
case 3:
n4 = (pSrc[ 2 ] & 0x3f);
n3 = ((pSrc[ 2 ] & 0xc0) >> 6);
case 2:
n3 |= ((pSrc[ 1 ] & 0x0f) << 2);
n2 = ((pSrc[ 1 ] & 0xf0) >> 4);
case 1:
n2 |= ((pSrc[ 0 ] & 0x03) << 4);
n1 = ((pSrc[ 0 ] & 0xfc) >> 2);
break;
default:
assert( false );
}
pSrc += dwBlockSize;
dwSrcSize -= dwBlockSize;
// Validate...
assert( 0 <= n1 && n1 <= 63 );
assert( 0 <= n2 && n2 <= 63 );
assert( 0 <= n3 && n3 <= 63 );
assert( 0 <= n4 && n4 <= 63 );
// Padding...
switch (dwBlockSize)
{
case 1: n3 = 64;
case 2: n4 = 64;
case 3:
break;
default:
assert( false );
}
// 4 outputs...
*pDest++ = BASE64_TABLE[ n1 ];
*pDest++ = BASE64_TABLE[ n2 ];
*pDest++ = BASE64_TABLE[ n3 ];
*pDest++ = BASE64_TABLE[ n4 ];
dwDestSize += BASE64_OUTPUT; //4
}
return dwDestSize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -