C面向接口编程和C++多态案例

案例背景:企业的信息系统一般都有成熟的框架,在框架内可以集成其他厂商的产品,但软件框架一般不发生变化。

案例需求:在企业信息系统框架中,集成其他厂商的socket通信产品和加密产品。

编程提示:

1、抽象通信接口结构体设计(CSocketProtocol)

2、框架接口设计( FrameWork:未加加密解密功能的框架、FrameWorkPro:增加加密解密功能的框架)

3、通信厂商1入围(CSckImp1)、通信厂商2入围(CSckImp2)

4、抽象加密接口结构体设计(CEncDesProtocol)、升级框架函数(增加加解密功能)、加密厂商1入围(CHwImp)、加密厂商2入围(CCiscoImp)

编程语言:分别用C和C++语言实现

C语言利用回调函数实现:

企业的通信接口定义

文件:CSocketProtocol.h

 1 #pragma once
 2
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #include <string.h>
 6
 7 /* 定义通信功能的抽象层接口 */
 8
 9 //定义类型名为Init_Socket的函数指针类型,实质是通信的初始化功能,功能的具体实现可以稍后实现,或者由其他厂商完成
10 typedef int(*Init_Socket)(void **handle);
11
12 //定义类型名为Send_Socket的函数指针类型,实质是通信的发送功能
13 typedef int(*Send_Socket)(void *handle, const unsigned char *buf, int bufLen);
14
15 //定义类型名为Recv_Socket的函数指针类型,实质是通信的接收功能
16 typedef int(*Recv_Socket)(void *handle, unsigned char *buf, int *bufLen);
17
18 //定义类型名为Recv_Socket的函数指针类型,实质是通信的销毁功能
19 typedef int(*Destroy_Socket)(void **handle);
20
21 //抽象层接口
22 typedef struct _CSocketProtocol
23 {
24     Init_Socket init;      //初始化报文功能
25     Send_Socket send;      //发送报文功能
26     Recv_Socket recv;      //接收报文功能
27     Destroy_Socket destroy;//销毁报文功能
28 }CSocketProtocol;
29
30 //接口初始化函数,把实例化的接口跟具体的函数进行绑定
31 int InitCSocketProtocol(CSocketProtocol *csp,
32     Init_Socket init,
33     Send_Socket send,
34     Recv_Socket recv,
35     Destroy_Socket destroy
36     );

CSocketProtocol.h

文件:CSocketProtocol.cpp

 1 #include "CSocketProtocol.h"
 2
 3 int InitCSocketProtocol(CSocketProtocol *csp,
 4     Init_Socket init,
 5     Send_Socket send,
 6     Recv_Socket recv,
 7     Destroy_Socket destroy
 8     )
 9 {
10     if (NULL == csp)
11     {
12         return -1;
13     }
14     if (NULL == init)
15     {
16         return -2;
17     }
18     if (NULL == send)
19     {
20         return -3;
21     }
22     if (NULL == recv)
23     {
24         return -4;
25     }
26     if (NULL == destroy)
27     {
28         return -5;
29     }
30     csp->init = init;
31     csp->send = send;
32     csp->recv = recv;
33     csp->destroy = destroy;
34     return 0;
35 }

CSocketProtocol.cpp

企业的加密接口定义

文件:CEncDesProtocol.h

 1 #pragma once
 2
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #include <string.h>
 6
 7 /* 定义加密解密功能的抽象层接口 */
 8
 9 //定义类型名为EncData的函数指针类型,实质是定义加密功能,功能的具体实现可以稍后实现,或者由其他厂商完成
10 typedef int(*EncData)(unsigned char *inBuf, int inBufLen, unsigned char *outBuf, int *outBufLen);
11
12 //定义类型名为DecData的函数指针类型,实质是定义解密功能,功能的具体实现可以稍后实现,或者由其他厂商完成
13 typedef int(*DecData)(unsigned char *inBuf, int inBufLen, unsigned char *outBuf, int *outBufLen);
14
15 //抽象层接口
16 typedef struct _EncDec
17 {
18     EncData enc;  //加密功能
19     DecData dec;  //解密功能
20 }EncDec;
21
22 //接口初始化函数,把实例化的接口跟具体的函数进行绑定
23 //ed : 接收加密解密接口的对象地址
24 //enc: 接收加密功能的函数的地址
25 //dec:接收解密功能的函数的地址
26 int Init_EncDec(EncDec *ed, EncData enc, DecData dec);

CEncDesProtocol.h

文件:CEncDesProtocol.cpp

 1 #include "CEncDesProtocol.h"
 2
 3
 4 int Init_EncDec(EncDec *ed, EncData enc, DecData dec)
 5 {
 6     if (NULL == ed)
 7     {
 8         return -1;
 9     }
10     if (NULL == enc)
11     {
12         return -2;
13     }
14     if (NULL == dec)
15     {
16         return -3;
17     }
18     ed->enc = enc;
19     ed->dec = dec;
20     return 0;
21 }

CEncDesProtocol.cpp

企业的软件框架:

文件:FrameWork.h

 1 #pragma once
 2
 3 #include "CSocketProtocol.h"
 4 #include "CEncDesProtocol.h"
 5
 6 //通信业务框架(报文未加密)
 7 //csp : 获取接口
 8 //sendBuf : 存放待发送的报文
 9 //sendLen : 存放待发送的报文长度
10 //recvBuf : 存放接收到的报文
11 //recvLen : 存放接收到的报文长度
12 void FrameWork(
13     CSocketProtocol *csp,
14     const unsigned char *sendBuf,
15     int sendLen,
16     unsigned char *recvBuf,
17     int *recvLen);
18
19 //通信业务框架(报文加密)
20 //csp : 获取接口
21 //sendBuf : 存放待发送的报文
22 //sendLen : 存放待发送的报文长度
23 //recvBuf : 存放接收到的报文
24 //recvLen : 存放接收到的报文长度
25 void FrameWorkPro(
26     CSocketProtocol *csp,
27     EncDec *ed,
28     const unsigned char *sendBuf,
29     int sendLen,
30     unsigned char *recvBuf,
31     int *recvLen);

FrameWork.h

文件:FrameWork.cpp

  1 #include "FrameWork.h"
  2
  3 void FrameWork(
  4     CSocketProtocol *csp,
  5     const unsigned char *sendBuf,
  6     int sendLen,
  7     unsigned char *recvBuf,
  8     int *recvLen)
  9 {
 10     void *handle = NULL;
 11     int ret = 0; //记录函数状态
 12
 13     //初始化句柄
 14     if (0 != (ret = csp->init(&handle)))
 15     {
 16         printf("csp->init error %d.\n", ret);
 17         return;
 18     }
 19
 20     //发送报文
 21     if (0 != (ret = csp->send(handle, sendBuf, sendLen)))
 22     {
 23         printf("csp->send error %d.\n", ret);
 24         csp->destroy(&handle);
 25         return;
 26     }
 27
 28     //接收报文
 29     if (0 != (ret = csp->recv(handle, recvBuf, recvLen)))
 30     {
 31         printf(" csp->recv error %d.\n", ret);
 32         csp->destroy(&handle);
 33         return;
 34     }
 35
 36     //销毁句柄
 37     if (0 != (ret = csp->destroy(&handle)))
 38     {
 39         printf(" csp->destroy error %d.\n", ret);
 40         return;
 41     }
 42 }
 43
 44 void FrameWorkPro(
 45     CSocketProtocol *csp,
 46     EncDec *ed,
 47     const unsigned char *sendBuf,
 48     int sendLen,
 49     unsigned char *recvBuf,
 50     int *recvLen)
 51 {
 52     void *handle = NULL;
 53     int ret = 0;
 54
 55     //初始化句柄
 56     if (0 != (ret = csp->init(&handle)))
 57     {
 58         printf("csp->init error %d.\n", ret);
 59         return;
 60     }
 61
 62     unsigned char encStr[1024] = { 0 };
 63     int encStrLen = 0;
 64
 65     //给报文加密
 66     ed->enc((unsigned char *)sendBuf, sendLen, encStr, &encStrLen);
 67
 68     //发送句柄
 69     if (0 != (ret = csp->send(handle, encStr, encStrLen)))
 70     {
 71         printf("csp->send error %d.\n", ret);
 72         csp->destroy(&handle);
 73         return;
 74     }
 75
 76     //保存接收到的密文
 77     unsigned char decStr[1024] = { 0 };
 78     int decStrLen = 0;
 79
 80     //接收报文
 81     if (0 != (ret = csp->recv(handle, decStr, &decStrLen)))
 82     {
 83         printf(" csp->recv error %d.\n", ret);
 84         csp->destroy(&handle);
 85         return;
 86     }
 87
 88     //打印报文
 89     printf("接收到的数据长度:%d\n", decStrLen);
 90     for (int i = 0; i < decStrLen; ++i)
 91     {
 92         printf("%c", decStr[i]);
 93     }
 94     printf("\n");
 95
 96     //给报文解密
 97     ed->dec(decStr, decStrLen, recvBuf, recvLen);
 98
 99     //销毁报文
100     csp->destroy(&handle);
101 }

FrameWork.cpp

第三方厂商根据企业的通信接口实现的通信功能

文件:CSckImp1.h

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4
 5 /* 厂商甲根据 "CSocketProtocol.h" 里头定义的通信抽象层,实现的接口 */
 6
 7 //通信报文结构
 8 typedef struct Handle
 9 {
10     unsigned char *data; //数据字符串
11     int len;             //数据长度
12 }Handle;
13
14 //实现通信初始化报文函数
15 //handle : 句柄的地址,给句柄分配空间
16 int Init_Socket1(void **handle);
17
18 //实现通信发送报文函数
19 //handle : 报文句柄
20 //buf : 待发送的报文
21 //bufLen : 待发送的报文长度
22 int Send_Socket1(void *handle, const unsigned char *buf, int bufLen);
23
24 //实现通信接收报文函数
25 //handle : 报文句柄
26 //buf : 存放接收到的报文
27 //bufLen : 存放接收到的报文长度
28 int Recv_Socket1(void *handle, unsigned char *buf, int *bufLen);
29
30 //实现销毁报文函数
31 //handle : 报文句柄地址
32 int Destroy_Socket1(void **handle);

CSckImp1.h

文件:CSckImp1.cpp

 1 #include "CSckImp1.h"
 2
 3 //通信初始化报文函数
 4 int Init_Socket1(void **handle)
 5 {
 6     if (NULL == handle)
 7     {
 8         return -1;
 9     }
10     Handle *hd = (Handle *)malloc(sizeof(Handle));
11     if (NULL == hd)
12     {
13         return -2;
14     }
15     hd->data = NULL;
16     hd->len = 0;
17     *handle = hd;
18     return 0;
19 }
20
21 //通信发送报文函数
22 int Send_Socket1(void *handle, const unsigned char *buf, int bufLen)
23 {
24     if (NULL == handle)
25     {
26         return -1;
27     }
28     if (NULL == buf)
29     {
30         return -2;
31     }
32     Handle *hd = (Handle *)handle;
33     hd->data = (unsigned char *)malloc(bufLen*sizeof(unsigned char));
34     if (NULL == hd->data)
35     {
36         return -3;
37     }
38     memcpy(hd->data, buf, bufLen);
39     hd->len = bufLen;
40     return 0;
41 }
42
43 //通信接收报文函数
44 int Recv_Socket1(void *handle, unsigned char *buf, int *bufLen)
45 {
46     if (NULL == handle)
47     {
48         return -1;
49     }
50     if (NULL == buf)
51     {
52         return -2;
53     }
54     if (NULL == bufLen)
55     {
56         return -3;
57     }
58     Handle *hd = (Handle *)handle;
59     memcpy(buf, hd->data, hd->len);
60     *bufLen = hd->len;
61     return 0;
62 }
63
64 //销毁报文函数
65 int Destroy_Socket1(void **handle)
66 {
67     Handle *hd = (Handle *)*handle;
68     if (NULL == hd)
69     {
70         return -1;
71     }
72     if (NULL != hd->data)
73     {
74         free(hd->data);
75         hd->data = NULL;
76     }
77     hd->len = 0;
78     return 0;
79 }

CSckImp1.cpp

第三方厂商根据企业的加密接口实现的加密解密功能

文件:des.h

 1 /*********************************************************
 2  *  des.h
 3  *  用户使用des算法头文件
 4  *
 5  *********************************************************/
 6 #ifndef _OPENDESS_H_
 7 #define _OPENDESS_H_
 8
 9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13 /* 厂商甲根据 "CEncDesProtocol.h" 里头定义的加密解密抽象层,实现的接口 */
14
15 //加密数据(encrypt:加密)
16 //pInData:明文数据
17 //nInDataLen:明文数据长度
18 //pOutData:加密后的数据
19 //pOutDataLen:加密数据的长度
20 int DesEnc(
21         unsigned char *pInData,
22         int            nInDataLen,
23         unsigned char *pOutData,
24         int           *pOutDataLen);
25
26
27 //解密数据(decrypt:解密)
28 //pInData:密文数据
29 //nInDataLen:密文数据长度
30 //pOutData:解密后的数据
31 //pOutDataLen:解密数据的长度
32 int DesDec(
33        unsigned char *pInData,
34        int            nInDataLen,
35        unsigned char *pOutData,
36        int           *pOutDataLen);
37
38 #ifdef __cplusplus
39 }
40 #endif
41
42 #endif

des.h

文件:des.cpp

  1 /******************************************************
  2  *
  3  *  des.c
  4  *  common des......
  5  *
  6  ******************************************************/
  7
  8 #include <stdlib.h>
  9 #include <string.h>
 10 #include <stdio.h>
 11 #include "des.h"
 12
 13 /*********************************************************
 14   data type definition for Des;
 15 **********************************************************/
 16 #define EN0    0
 17 #define DE1    1
 18
 19 #define DES_KEYBYTES    128
 20 #define DES_KEYLONGS    32
 21 #define DES_BLOCKLEN    8
 22
 23 typedef struct {
 24     unsigned char ek[DES_KEYBYTES];
 25     int    ekLen;
 26     unsigned char dk[DES_KEYBYTES];
 27     int    dkLen;
 28     unsigned char CbcCtx[DES_BLOCKLEN];
 29 } DES_CTX;
 30
 31 typedef struct {
 32     unsigned char ek1[DES_KEYBYTES];
 33     int    ek1Len;
 34     unsigned char dk1[DES_KEYBYTES];
 35     int    dk1Len;
 36     unsigned char ek2[DES_KEYBYTES];
 37     int    ek2Len;
 38     unsigned char dk2[DES_KEYBYTES];
 39     int    dk2Len;
 40     unsigned char CbcCtx[DES_BLOCKLEN];
 41     //int    IsFirstBlock;
 42 } DES3_CTX;
 43
 44
 45 static unsigned char pc1[56] = {
 46     56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,
 47      9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35,
 48     62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
 49     13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3 };
 50
 51 static unsigned char pc2[48] = {
 52     13, 16, 10, 23,  0,  4,         2, 27, 14,  5, 20,  9,
 53     22, 18, 11,  3, 25,  7,     15,  6, 26, 19, 12,  1,
 54     40, 51, 30, 36, 46, 54,        29, 39, 50, 44, 32, 47,
 55     43, 48, 38, 55, 33, 52,     45, 41, 49, 35, 28, 31 };
 56
 57 static unsigned short bytebit[8] = {0200,0100,040,020,010,04,02,01 };
 58 static unsigned char totrot[16] = {1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28};
 59 static unsigned long bigbyte[24] = {
 60     0x800000L,    0x400000L,    0x200000L,    0x100000L,
 61     0x80000L,    0x40000L,    0x20000L,    0x10000L,
 62     0x8000L,    0x4000L,    0x2000L,    0x1000L,
 63     0x800L,        0x400L,        0x200L,        0x100L,
 64     0x80L,        0x40L,        0x20L,        0x10L,
 65     0x8L,        0x4L,        0x2L,        0x1L    };
 66
 67 //insert digits
 68 static unsigned long SP1[64] ={
 69        0x01010400l,0x00000000l,0x00010000l,0x01010404l,
 70        0x01010004l,0x00010404l,0x00000004l,0x00010000l,
 71        0x00000400l,0x01010400l,0x01010404l,0x00000400l,
 72        0x01000404l,0x01010004l,0x01000000l,0x00000004l,
 73        0x00000404l,0x01000400l,0x01000400l,0x00010400l,
 74        0x00010400l,0x01010000l,0x01010000l,0x01000404l,
 75        0x00010004l,0x01000004l,0x01000004l,0x00010004l,
 76        0x00000000l,0x00000404l,0x00010404l,0x01000000l,
 77        0x00010000l,0x01010404l,0x00000004l,0x01010000l,
 78        0x01010400l,0x01000000l,0x01000000l,0x00000400l,
 79        0x01010004l,0x00010000l,0x00010400l,0x01000004l,
 80        0x00000400l,0x00000004l,0x01000404l,0x00010404l,
 81        0x01010404l,0x00010004l,0x01010000l,0x01000404l,
 82        0x01000004l,0x00000404l,0x00010404l,0x01010400l,
 83        0x00000404l,0x01000400l,0x01000400l,0x00000000l,
 84        0x00010004l,0x00010400l,0x00000000l,0x01010004l };
 85
 86
 87 static unsigned long SP2[64]={
 88        0x80108020l,0x80008000l,0x00008000l,0x00108020l,
 89        0x00100000l,0x00000020l,0x80100020l,0x80008020l,
 90        0x80000020l,0x80108020l,0x80108000l,0x80000000l,
 91        0x80008000l,0x00100000l,0x00000020l,0x80100020l,
 92        0x00108000l,0x00100020l,0x80008020l,0x00000000l,
 93        0x80000000l,0x00008000l,0x00108020l,0x80100000l,
 94        0x00100020l,0x80000020l,0x00000000l,0x00108000l,
 95        0x00008020l,0x80108000l,0x80100000l,0x00008020l,
 96        0x00000000l,0x00108020l,0x80100020l,0x00100000l,
 97        0x80008020l,0x80100000l,0x80108000l,0x00008000l,
 98        0x80100000l,0x80008000l,0x00000020l,0x80108020l,
 99        0x00108020l,0x00000020l,0x00008000l,0x80000000l,
100        0x00008020l,0x80108000l,0x00100000l,0x80000020l,
101        0x00100020l,0x80008020l,0x80000020l,0x00100020l,
102        0x00108000l,0x00000000l,0x80008000l,0x00008020l,
103        0x80000000l,0x80100020l,0x80108020l,0x00108000l };
104
105
106 static unsigned long SP3[64]={
107        0x00000208l,0x08020200l,0x00000000l,0x08020008l,
108        0x08000200l,0x00000000l,0x00020208l,0x08000200l,
109        0x00020008l,0x08000008l,0x08000008l,0x00020000l,
110        0x08020208l,0x00020008l,0x08020000l,0x00000208l,
111        0x08000000l,0x00000008l,0x08020200l,0x00000200l,
112        0x00020200l,0x08020000l,0x08020008l,0x00020208l,
113        0x08000208l,0x00020200l,0x00020000l,0x08000208l,
114        0x00000008l,0x08020208l,0x00000200l,0x08000000l,
115        0x08020200l,0x08000000l,0x00020008l,0x00000208l,
116        0x00020000l,0x08020200l,0x08000200l,0x00000000l,
117        0x00000200l,0x00020008l,0x08020208l,0x08000200l,
118        0x08000008l,0x00000200l,0x00000000l,0x08020008l,
119        0x08000208l,0x00020000l,0x08000000l,0x08020208l,
120        0x00000008l,0x00020208l,0x00020200l,0x08000008l,
121        0x08020000l,0x08000208l,0x00000208l,0x08020000l,
122        0x00020208l,0x00000008l,0x08020008l,0x00020200l };
123
124
125 static unsigned long SP4[64]={
126        0x00802001l,0x00002081l,0x00002081l,0x00000080l,
127        0x00802080l,0x00800081l,0x00800001l,0x00002001l,
128        0x00000000l,0x00802000l,0x00802000l,0x00802081l,
129        0x00000081l,0x00000000l,0x00800080l,0x00800001l,
130        0x00000001l,0x00002000l,0x00800000l,0x00802001l,
131        0x00000080l,0x00800000l,0x00002001l,0x00002080l,
132        0x00800081l,0x00000001l,0x00002080l,0x00800080l,
133        0x00002000l,0x00802080l,0x00802081l,0x00000081l,
134        0x00800080l,0x00800001l,0x00802000l,0x00802081l,
135        0x00000081l,0x00000000l,0x00000000l,0x00802000l,
136        0x00002080l,0x00800080l,0x00800081l,0x00000001l,
137        0x00802001l,0x00002081l,0x00002081l,0x00000080l,
138        0x00802081l,0x00000081l,0x00000001l,0x00002000l,
139        0x00800001l,0x00002001l,0x00802080l,0x00800081l,
140        0x00002001l,0x00002080l,0x00800000l,0x00802001l,
141        0x00000080l,0x00800000l,0x00002000l,0x00802080l };
142
143
144 static unsigned long SP5[64]={
145        0x00000100l,0x02080100l,0x02080000l,0x42000100l,
146        0x00080000l,0x00000100l,0x40000000l,0x02080000l,
147        0x40080100l,0x00080000l,0x02000100l,0x40080100l,
148        0x42000100l,0x42080000l,0x00080100l,0x40000000l,
149        0x02000000l,0x40080000l,0x40080000l,0x00000000l,
150        0x40000100l,0x42080100l,0x42080100l,0x02000100l,
151        0x42080000l,0x40000100l,0x00000000l,0x42000000l,
152        0x02080100l,0x02000000l,0x42000000l,0x00080100l,
153        0x00080000l,0x42000100l,0x00000100l,0x02000000l,
154        0x40000000l,0x02080000l,0x42000100l,0x40080100l,
155        0x02000100l,0x40000000l,0x42080000l,0x02080100l,
156        0x40080100l,0x00000100l,0x20000000l,0x42080000l,
157        0x42080100l,0x00080100l,0x42000000l,0x42080100l,
158        0x02080000l,0x02000100l,0x40000100l,0x00080000l,
159        0x00080100l,0x02000100l,0x40000100l,0x00080000l,
160        0x00000000l,0x40080000l,0x02080100l,0x40000100l };
161
162
163 static unsigned long SP6[64]={
164        0x20000010l,0x20400000l,0x00004000l,0x20404010l,
165        0x20400000l,0x00000010l,0x20404010l,0x00400000l,
166        0x20004000l,0x00404010l,0x00400000l,0x20000010l,
167        0x00400010l,0x20004000l,0x20000000l,0x00004010l,
168        0x00000000l,0x00400010l,0x20004010l,0x00004000l,
169        0x00404000l,0x20004010l,0x00000010l,0x20400010l,
170        0x20400010l,0x00000000l,0x00404010l,0x20404000l,
171        0x00004010l,0x00404000l,0x20404000l,0x20000000l,
172        0x20004000l,0x00000010l,0x20400010l,0x00404000l,
173        0x20404010l,0x00400000l,0x00004010l,0x20000010l,
174        0x00400000l,0x20004000l,0x20000000l,0x00004010l,
175        0x20000010l,0x20404010l,0x00404000l,0x20400000l,
176        0x00404010l,0x20404000l,0x00000000l,0x20400010l,
177        0x00000010l,0x00004000l,0x20400000l,0x00404010l,
178        0x00004000l,0x00400010l,0x20004010l,0x00000000l,
179        0x20404000l,0x20000000l,0x00400010l,0x20004010l };
180
181 static unsigned long SP7[64] = {
182     0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
183     0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
184     0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
185     0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
186     0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
187     0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
188     0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
189     0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
190     0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
191     0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
192     0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
193     0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
194     0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
195     0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
196     0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
197     0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
198
199 static unsigned long SP8[64] = {
200     0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
201     0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
202     0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
203     0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
204     0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
205     0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
206     0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
207     0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
208     0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
209     0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
210     0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
211     0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
212     0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
213     0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
214     0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
215     0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
216
217 void deskey(unsigned char *key,short edf, unsigned long *kn);
218 void cookey(register unsigned long *raw1, unsigned long *dough);
219 //void cpkey(register unsigned long *into);
220 //void usekey(register unsigned long *from);
221 //void des(unsigned char *inblock,unsigned char *outblock);
222 void scrunch(register unsigned char *outof, register unsigned long *into);
223 void unscrun(register unsigned long *outof, register unsigned char *into);
224 void desfunc(register unsigned long *block,register unsigned long *keys);
225
226 /*****************  DES Function  *****************/
227 unsigned long OPENCOMM_DesExpandEncKey(
228         unsigned char *pbDesKey,
229         unsigned long  ulDesKeyLen,
230         unsigned char *pbDesEncKey,
231         unsigned long *ulDesEncKeyLen);
232
233 unsigned long OPENCOMM_DesExpandDecKey(
234         unsigned char *pbDesKey,
235         unsigned long  ulDesKeyLen,
236         unsigned char *pbDesDecKey,
237         unsigned long *ulDesDecKeyLen);
238
239 unsigned long OPENCOMM_DesEncRaw(
240         unsigned char *pbDesEncKey,
241         unsigned long  ulDesEncKeyLen,
242         unsigned char *pbInData,
243         unsigned long  ulInDataLen,
244         unsigned char *pbOutData,
245         unsigned long *ulOutDataLen);
246
247 unsigned long OPENCOMM_DesDecRaw(
248         unsigned char *pbDesDecKey,
249         unsigned long  ulDesDecKeyLen,
250         unsigned char *pbInData,
251         unsigned long  ulInDataLen,
252         unsigned char *pbOutData,
253         unsigned long *ulOutDataLen);
254
255
256 int myic_DESDecrypt(
257         unsigned char *pDesKey,
258         int            nDesKeyLen,
259         unsigned char *pInData,
260         int            nInDataLen,
261         unsigned char *pOutData,
262         int           *pOutDataLen);
263
264 int myic_DESEncrypt(
265         unsigned char *pDesKey,
266         int            nDesKeyLen,
267         unsigned char *pInData,
268         int            nInDataLen,
269         unsigned char *pOutData,
270         int           *pOutDataLen);
271
272
273 void deskey(unsigned char *key,short edf, unsigned long *kn)
274 {
275     register int i, j, l, m, n;
276     unsigned long pc1m[56],pcr[56];
277
278
279     for ( j = 0; j < 56; j++ )
280     {
281         l = pc1[j];
282         m = l & 07;
283         pc1m[j] = (((unsigned long) key[l >> 3] & (unsigned long)bytebit[m] ) ? 1:0);
284     }
285     for ( i = 0;i < 16; i++)
286     {
287         if ( edf == DE1 )    m = (15 - i) << 1;
288         else    m = i << 1;
289         n = m + 1;
290         kn[m] = kn[n] = 0L;
291         for ( j = 0; j < 28; j++ )
292         {
293             l = j + totrot[i];
294             if ( l < 28 )    pcr[j] = pc1m[l];
295             else    pcr[j] = pc1m[l-28];
296         }
297         for (j = 28; j < 56; j++ )
298         {
299             l = j + totrot[i];
300             if ( l < 56 )    pcr[j] = pc1m[l];
301             else    pcr[j] = pc1m[l-28];
302         }
303         for ( j = 0; j < 24; j++ )
304         {
305             if ( pcr[pc2[j]] )    kn[m] |= bigbyte[j];
306             if ( pcr[pc2[j+24]] )    kn[n] |= bigbyte[j];
307         }
308     }
309     return;
310 }
311
312 void cookey(register unsigned long *raw1, unsigned long *dough)
313 {
314     register unsigned long *cook,*raw0;
315     register int i;
316
317     cook = dough;
318     for ( i = 0; i < 16; i++, raw1++ ) {
319         raw0 = raw1++;
320         *cook     = (*raw0 & 0x00fc0000L) << 6;
321         *cook    |= (*raw0 & 0x00000fc0L) << 10;
322         *cook    |= (*raw1 & 0x00fc0000L) >> 10;
323         *cook++    |= (*raw1 & 0x00000fc0L) >> 6;
324         *cook     = (*raw0 & 0x0003f000L) << 12;
325         *cook    |= (*raw0 & 0x0000003fL) << 16;
326         *cook    |= (*raw1 & 0x0003f000L) >> 4;
327         *cook++    |= (*raw1 & 0x0000003fL);
328     }
329     return;
330 }
331
332 void scrunch(register unsigned char *outof, register unsigned long *into)
333 {
334     *into     = (*outof++ & 0xffL) << 24;
335     *into    |= (*outof++ & 0xffL) << 16;
336     *into    |= (*outof++ & 0xffL) << 8;
337     *into++    |= (*outof++ & 0xffL);
338     *into     = (*outof++ & 0xffL) << 24;
339     *into    |= (*outof++ & 0xffL) << 16;
340     *into    |= (*outof++ & 0xffL) << 8;
341     *into++    |= (*outof   & 0xffL);
342     return;
343 }
344
345 void unscrun(register unsigned long *outof, register unsigned char *into)
346 {
347     *into++     = (unsigned char)((*outof >> 24) & 0xffL);
348     *into++     = (unsigned char)((*outof >> 16) & 0xffL);
349     *into++     = (unsigned char)((*outof >>  8) & 0xffL);
350     *into++     = (unsigned char)( *outof++      & 0xffL);
351     *into++     = (unsigned char)((*outof >> 24) & 0xffL);
352     *into++     = (unsigned char)((*outof >> 16) & 0xffL);
353     *into++     = (unsigned char)((*outof >>  8) & 0xffL);
354     *into     = (unsigned char)( *outof          & 0xffL);
355     return;
356 }
357
358 void desfunc(register unsigned long *block,register unsigned long *keys)
359 {
360     register unsigned long fval, work, right, leftt;
361     register int round;
362
363     leftt = block[0];
364     right = block[1];
365     work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
366
367     right ^= work;
368     leftt ^= (work << 4);
369     work = ((leftt >> 16) ^ right) & 0x0000ffffL;
370
371     right ^= work;
372     leftt ^= (work << 16);
373     work = ((right >> 2) ^ leftt) & 0x33333333L;
374
375     leftt ^= work;
376     right ^= (work << 2);
377     work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
378
379     leftt ^= work;
380     right ^= (work << 8);
381     right = ((right << 1) | ((right >>31) & 1L)) & 0xffffffffL;
382     work = (leftt ^ right) & 0xaaaaaaaaL;
383
384     leftt ^= work;
385     right ^= work;
386     leftt = ((leftt << 1) | ((leftt >> 31)&1L)) & 0xffffffffL;
387
388     for (round = 0; round < 8; round++) {
389         work  = (right << 28) | (right >> 4);
390         work ^= *keys++;
391         fval  = SP7[ work    & 0x3fL];
392         fval |= SP5[(work >>  8) & 0x3fL];
393         fval |= SP3[(work >> 16) & 0x3fL];
394         fval |= SP1[(work >> 24) & 0x3fL];
395         work  = right ^ *keys++;
396         fval |= SP8[ work     & 0x3fL];
397         fval |= SP6[(work >>  8) & 0x3fL];
398         fval |= SP4[(work >> 16) & 0x3fL];
399         fval |= SP2[(work >> 24) & 0x3fL];
400         leftt ^= fval;
401         work  = (leftt << 28) | (leftt >> 4);
402         work ^= *keys++;
403         fval  = SP7[ work     & 0x3fL];
404         fval |= SP5[(work >>  8) & 0x3fL];
405         fval |= SP3[(work >> 16) & 0x3fL];
406         fval |= SP1[(work >> 24) & 0x3fL];
407         work  = leftt ^ *keys++;
408         fval |= SP8[ work     & 0x3fL];
409         fval |= SP6[(work >>  8) & 0x3fL];
410         fval |= SP4[(work >> 16) & 0x3fL];
411         fval |= SP2[(work >> 24) & 0x3fL];
412         right ^= fval;
413     }
414
415     right = (right << 31) | (right >> 1);
416     work = (leftt ^ right) & 0xaaaaaaaaL;
417     leftt ^= work;
418     right ^= work;
419     leftt = (leftt << 31) | (leftt >> 1);
420     work = ((leftt >>  8) ^ right) & 0x00ff00ffL;
421     right ^= work;
422     leftt ^= (work << 8);
423     work = ((leftt >>  2) ^ right) & 0x33333333L;
424     right ^= work;
425     leftt ^= (work << 2);
426     work = ((right >> 16) ^ leftt) & 0x0000ffffL;
427     leftt ^= work;
428     right ^= (work << 16);
429     work = ((right >>  4) ^ leftt) & 0x0f0f0f0fL;
430     leftt ^= work;
431     right ^= (work << 4);
432     *block++ = right;
433     *block = leftt;
434     return;
435 }
436
437 /*****************************************************************
438     OPENCOMM_DesExpandEncKey    : Expand Des Enc Key 扩展des加密密钥
439     Return value:
440         0         : Success
441         other     : failed
442     Parameters:
443         pbDesKey        : 扩展前的DES密钥(8字节)       input
444         ulDesKeyLen     : 扩展前的DES密钥长度          input
445         pbDesEncKey     : 扩展后的DES加密密钥(128字节)  output
446         *ulDesEncKeyLen : 扩展后的DES加密密钥长度       output
447 *****************************************************************/
448 unsigned long OPENCOMM_DesExpandEncKey(
449         unsigned char *pbDesKey,
450         unsigned long  ulDesKeyLen,
451         unsigned char *pbDesEncKey,
452         unsigned long *ulDesEncKeyLen)
453 {
454     unsigned long kn[32], dough[32];
455
456     if (ulDesKeyLen != 8)
457         return 0xEE20;
458
459     deskey(pbDesKey, EN0, kn);
460     cookey(kn, dough);
461     *ulDesEncKeyLen = DES_KEYBYTES;  //32 long = 128 bytes
462     memcpy(pbDesEncKey, dough, *ulDesEncKeyLen);
463
464     return 0;
465 }
466
467 /*****************************************************************
468     OPENCOMM_DesExpandDecKey    : Expand Des Dec Key 扩展des解密密钥
469     Return value:
470         0       : Success
471         other   : failed
472     Parameters:
473         pbDesKey        : 扩展前的DES密钥(8字节)      input
474         ulDesKeyLen     : 扩展前的DES密钥长度         input
475         pbDesDecKey     : 扩展后的DES解密密钥(128字节) output
476         *ulDesDecKeyLen : 扩展后的DES解密密钥长度      output
477 *****************************************************************/
478 unsigned long OPENCOMM_DesExpandDecKey(
479         unsigned char *pbDesKey,
480         unsigned long  ulDesKeyLen,
481         unsigned char *pbDesDecKey,
482         unsigned long *ulDesDecKeyLen)
483 {
484     unsigned long kn[32], dough[32];
485
486     if (ulDesKeyLen != 8)
487         return 0xEE20;
488
489     deskey(pbDesKey, DE1, kn);
490     cookey(kn, dough);
491     *ulDesDecKeyLen = DES_KEYBYTES;  //32 long = 128 bytes
492     memcpy(pbDesDecKey, dough, *ulDesDecKeyLen);
493
494     return 0;
495 }
496
497 /****************************************************************
498     OPENCOMM_DesEncRaw        : Des算法加密小整块明文8字节
499     Return value:
500         0       : Success
501         other   : failed
502     Parameters:
503         pbDesEncKey    : DES加密密钥    input
504         ulDesEncKeyLen : DES加密密钥长度 input
505         pbInData       : 待加密的明文    input
506         ulInDataLen    : 待加密的明文长度 input
507         pbOutData      : 加密后的密文    output
508         *ulOutDataLen  : 加密后的密文长度 output
509 *****************************************************************/
510 unsigned long OPENCOMM_DesEncRaw(
511         unsigned char *pbDesEncKey,
512         unsigned long  ulDesEncKeyLen,
513         unsigned char *pbInData,
514         unsigned long  ulInDataLen,
515         unsigned char *pbOutData,
516         unsigned long *ulOutDataLen)
517 {
518     unsigned long work[2], ek[DES_KEYLONGS];
519     unsigned char cp[DES_BLOCKLEN];
520
521     if (ulInDataLen != DES_BLOCKLEN)
522         return 0xEE20;
523
524     if (ulDesEncKeyLen != DES_KEYBYTES)
525         return 0xEE20;
526
527     memcpy(cp, pbInData, DES_BLOCKLEN);
528     scrunch(cp,work);  // 8 bytes -> 2 long
529     memcpy(ek, pbDesEncKey, ulDesEncKeyLen);
530     desfunc(work,ek);
531     unscrun(work,cp); // 2 long -> 8 bytes
532     memcpy(pbOutData, cp, DES_BLOCKLEN);
533     *ulOutDataLen = DES_BLOCKLEN;
534
535     return 0;
536 }
537
538 /*****************************************************************
539     OPENCOMM_DesDecRaw : Des算法解密小整块密文8字节
540     Return value:
541         0     : Success
542         other : failed
543     Parameters:
544         pbDesDecKey    : DES解密密钥     input
545         ulDesDecKeyLen : DES解密密钥长度  input
546         pbInData       : 待解密的密文     input
547         ulInDataLen    : 待解密的密文长度  input
548         pbOutData      : 解密后的明文     output
549         *ulOutDataLen  : 解密后的明文长度  output
550 *****************************************************************/
551 unsigned long OPENCOMM_DesDecRaw(
552         unsigned char *pbDesDecKey,
553         unsigned long  ulDesDecKeyLen,
554         unsigned char *pbInData,
555         unsigned long  ulInDataLen,
556         unsigned char *pbOutData,
557         unsigned long *ulOutDataLen)
558 {
559     unsigned long work[2], dk[DES_KEYLONGS];
560     unsigned char cp[DES_BLOCKLEN];
561
562     if (ulInDataLen != DES_BLOCKLEN)
563         return 0xEE20;
564
565     if (ulDesDecKeyLen != DES_KEYBYTES)
566         return 0xEE20;
567
568     memcpy(cp, pbInData, DES_BLOCKLEN);
569     scrunch(cp,work);  // 8 bytes -> 2 long
570     memcpy(dk, pbDesDecKey, ulDesDecKeyLen);
571     desfunc(work,dk);
572     unscrun(work,cp); // 2 long -> 8 bytes
573     memcpy(pbOutData, cp, DES_BLOCKLEN);
574 //    des_enc(pbDesEncKey, pbInData, pbOutData);
575     *ulOutDataLen = DES_BLOCKLEN;
576
577     return 0;
578 }
579
580 /*********************   DES    *********************/
581
582 int myic_DESEncrypt(
583         unsigned char *pDesKey,
584         int            nDesKeyLen,
585         unsigned char *pInData,
586         int            nInDataLen,
587         unsigned char *pOutData,
588         int           *pOutDataLen)
589 {
590     unsigned char DesKeyBuf[32];
591     unsigned char DesEncKeyBuf[128];
592     int EncKeyLen, KeyLen = 0;
593     int retval = 0, loops, i;
594
595     if(nInDataLen%8 != 0)
596         return 0xEE20;
597
598     if(nDesKeyLen != 8)
599         return 0xEE20;
600     KeyLen = nDesKeyLen;
601     memcpy(DesKeyBuf, pDesKey, nDesKeyLen);
602
603
604     retval = OPENCOMM_DesExpandEncKey(DesKeyBuf, KeyLen,
605         DesEncKeyBuf, (unsigned long *)&EncKeyLen);
606     if(retval != 0)
607         return retval;
608
609     loops = nInDataLen/8;
610     for(i = 0; i < loops; i++)
611     {
612         retval = OPENCOMM_DesEncRaw(DesEncKeyBuf, EncKeyLen, pInData + i*8,
613             8, pOutData + i*8, (unsigned long *)pOutDataLen);
614         if(retval != 0)
615             return retval;
616     }
617     *pOutDataLen = nInDataLen;
618     return retval;
619 }
620
621
622 int myic_DESDecrypt(
623         unsigned char *pDesKey,
624         int            nDesKeyLen,
625         unsigned char *pInData,
626         int            nInDataLen,
627         unsigned char *pOutData,
628         int           *pOutDataLen)
629 {
630     unsigned char DesKeyBuf[32];
631     unsigned char DesDecKeyBuf[128];
632     int DecKeyLen, KeyLen = 0;
633     int retval = 0, loops, i;
634
635     if(nInDataLen%8 != 0)
636         return 0xEE20;
637
638     if(nDesKeyLen != 8)
639         return 0xEE20;
640     KeyLen = nDesKeyLen;
641     memcpy(DesKeyBuf, pDesKey, nDesKeyLen);
642
643     retval = OPENCOMM_DesExpandDecKey(DesKeyBuf, KeyLen,
644         DesDecKeyBuf, (unsigned long *)&DecKeyLen);
645     if(retval != 0)
646         return retval;
647
648     loops = nInDataLen/8;
649     for(i = 0; i < loops; i++)
650     {
651         retval = OPENCOMM_DesDecRaw(DesDecKeyBuf, DecKeyLen, pInData + i*8,
652             8, pOutData + i*8, (unsigned long *)pOutDataLen);
653         if(retval != 0)
654             return retval;
655     }
656     *pOutDataLen = nInDataLen;
657     return retval;
658 }
659
660
661 //对称明文数据打pading
662 void  CW_dataPadAdd(int tag, unsigned char *date, unsigned int dateLen,
663                     unsigned char **padDate, unsigned int *padDateLen)
664 {
665     int           i, padLen;
666     unsigned char *pTmp   = NULL;
667
668     pTmp = (unsigned char *)malloc(dateLen+24);
669     if (pTmp == NULL)
670     {
671         *padDate = NULL;
672         return ;
673     }
674     memset(pTmp, 0, dateLen+24);
675     memcpy(pTmp, date, dateLen);
676
677     if (tag == 0)
678     {
679         padLen = 8 - dateLen % 8;
680         for (i=0; i<padLen; i++)
681         {
682             pTmp[dateLen+i] = (char)padLen;
683         }
684         *padDateLen = dateLen + padLen;
685     }
686     else
687     {
688         padLen = 16 - dateLen % 16;
689         for (i=0; i<padLen; i++)
690         {
691             pTmp[dateLen+i] = (char)padLen;
692         }
693     }
694
695     *padDateLen = dateLen + padLen;
696     *padDate = pTmp;
697 }
698
699 #define  USER_PASSWORD_KEY "abcd1234"
700
701
702 //数据加密
703 int DesEnc(
704          unsigned char *pInData,
705          int            nInDataLen,
706          unsigned char *pOutData,
707          int           *pOutDataLen)
708 {
709     int                rv;
710     unsigned char    *padDate = NULL;
711     unsigned int    padDateLen = 0;
712
713     CW_dataPadAdd(0, pInData, (unsigned int )nInDataLen, &padDate, &padDateLen);
714
715     rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
716         padDate, (int)padDateLen, pOutData, pOutDataLen);
717     if (rv != 0)
718     {
719         if (padDate != NULL)
720         {
721             free(padDate);
722         }
723         return rv;
724     }
725
726     if (padDate != NULL)
727     {
728         free(padDate);
729     }
730     return 0;
731 }
732
733
734 //数据加密
735 int DesEnc_raw(
736     unsigned char *pInData,
737     int            nInDataLen,
738     unsigned char *pOutData,
739     int           *pOutDataLen)
740 {
741     int                rv;
742     unsigned char    *padDate = NULL;
743     unsigned int    padDateLen = 0;
744
745     rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
746         pInData, (int)nInDataLen, pOutData, pOutDataLen);
747     if (rv != 0)
748     {
749         return rv;
750     }
751     return 0;
752 }
753
754 //解密分配内存错误
755 #define  ERR_MALLOC 20
756 //密码长度不是8的整数倍, 不合法
757 #define  ERR_FILECONT 20
758
759
760 //用户使用函数des解密
761 int DesDec(
762            unsigned char *pInData,
763            int            nInDataLen,
764            unsigned char *pOutData,
765            int           *pOutDataLen)
766 {
767     int                rv;
768     char            padChar;
769     unsigned char     *tmpPlain = NULL;
770
771     tmpPlain =        (unsigned char *)malloc(nInDataLen+24);
772     if (tmpPlain == NULL)
773     {
774         return ERR_MALLOC;
775     }
776     memset(tmpPlain, 0, nInDataLen+24);
777
778     //解密
779     rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
780         pInData, nInDataLen, tmpPlain, pOutDataLen);
781     if (rv != 0)
782     {
783         if (tmpPlain != NULL) free(tmpPlain);
784         return rv;
785     }
786
787     //去pading
788     padChar = tmpPlain[*pOutDataLen - 1];
789     if ( (int)padChar<=0 || (int)padChar>8) //异常处理
790     {
791         if (tmpPlain) free(tmpPlain);
792         return ERR_FILECONT;
793     }
794
795     *pOutDataLen = *pOutDataLen - (int)padChar;
796     //memset(tmpPlain + *pOutDataLen, 0, (int)padChar);
797     memcpy(pOutData, tmpPlain, *pOutDataLen);
798     if (tmpPlain) free(tmpPlain);
799     return 0;
800 }
801
802
803 //用户使用函数des解密
804 int DesDec_raw(
805     unsigned char *pInData,
806     int            nInDataLen,
807     unsigned char *pOutData,
808     int           *pOutDataLen)
809 {
810     int                rv;
811     //char            padChar;
812     //unsigned char     *tmpPlain = NULL;
813
814     /*
815     tmpPlain =        (unsigned char *)malloc(nInDataLen+24);
816     if (tmpPlain == NULL)
817     {
818         return ERR_MALLOC;
819     }
820     memset(tmpPlain, 0, nInDataLen+24);
821     */
822
823     //解密
824     rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
825         pInData, nInDataLen, pOutData, pOutDataLen);
826     if (rv != 0)
827     {
828         //if (tmpPlain != NULL) free(tmpPlain);
829         return rv;
830     }
831     /*
832     //去pading
833     padChar = tmpPlain[*pOutDataLen - 1];
834     if ( (int)padChar<=0 || (int)padChar>8) //异常处理
835     {
836         if (tmpPlain) free(tmpPlain);
837         return ERR_FILECONT;
838     }
839
840     *pOutDataLen = *pOutDataLen - (int)padChar;
841     //memset(tmpPlain + *pOutDataLen, 0, (int)padChar);
842     memcpy(pOutData, tmpPlain, *pOutDataLen);
843     if (tmpPlain) free(tmpPlain);
844     */
845     return 0;
846 }

des.cpp

集成测试main函数

 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include "CSckImp1.h"
 3 #include "CSocketProtocol.h"
 4 #include "CEncDesProtocol.h"
 5 #include "des.h"
 6 #include "FrameWork.h"
 7
 8 //测试FrameWork
 9 void TestFrameWork()
10 {
11     //实例化通信接口
12     CSocketProtocol csp;
13
14     //给通信接口初始化,绑定具体实现的函数
15     InitCSocketProtocol(&csp, Init_Socket1, Send_Socket1, Recv_Socket1, Destroy_Socket1);
16
17     //保存接收的报文
18     unsigned char recvBuf[1024] = { 0 };
19     int recvLen = 0;
20
21     //保存发送的报文
22     unsigned char sendBuf[1024] = { 0 };
23
24     //组装报文
25     int sendLen = sprintf((char *)sendBuf, "%s%c%s%c", "hello", 0, "world", 0);
26
27     //执行业务
28     FrameWork(&csp, sendBuf, sendLen, recvBuf, &recvLen);
29
30     //打印接收到的报文
31     printf("接收到的数据长度:%d\n", recvLen);
32     for (int i = 0; i < recvLen; ++i)
33     {
34         printf("%c", recvBuf[i]);
35     }
36     printf("\n");
37 }
38
39 //测试FrameWorkPro
40 void TestFrameWorkPro()
41 {
42     CSocketProtocol csp; //实例化通信接口
43     EncDec ed;           //实例化加密解密接口
44
45     //给通信接口初始化,绑定具体实现的函数
46     InitCSocketProtocol(&csp, Init_Socket1, Send_Socket1, Recv_Socket1, Destroy_Socket1);
47
48     //给加密解密接口初始化,绑定具体实现的函数
49     Init_EncDec(&ed, DesEnc, DesDec);
50
51     //保存接收的报文
52     unsigned char recvBuf[1024] = { 0 };
53     int recvLen = 0;
54
55     //保存发送的报文
56     unsigned char sendBuf[1024] = { 0 };
57
58     //组装报文
59     int sendLen = sprintf((char *)sendBuf, "We never know what will happen in the future");
60
61     //执行业务
62     FrameWorkPro(&csp, &ed, sendBuf, sendLen, recvBuf, &recvLen);
63
64     //打印接收到的报文
65     printf("接收到的数据长度:%d\n", recvLen);
66     for (int i = 0; i < recvLen; ++i)
67     {
68         printf("%c", recvBuf[i]);
69     }
70     printf("\n");
71 }
72
73 int main(void)
74 {
75     //TestFrameWork();
76     TestFrameWorkPro();
77     return 0;
78 }

main

C++语言利用多态实现:只集成通信功能

企业的通信接口定义:

文件:CSocketProtocol.h

 1 #pragma once
 2 #include <iostream>
 3 using namespace std;
 4
 5 //抽象层:定义通信接口
 6 class CSocketProtocol
 7 {
 8 public:
 9     //初始化句柄
10     virtual int Init_Socket() = 0;
11
12     //发送报文
13     virtual int Send_Socket(const unsigned char *buf, int bufLen) = 0;
14
15     //接收报文
16     virtual int Recv_Socket(unsigned char *buf, int *bufLen) = 0;
17
18     //销毁句柄
19     virtual int Destroy_Socket() = 0;
20 };

CSocketProtocol.h

第三方厂商根据企业的通信接口实现的通信功能

文件:CSckImp1.h

 1 #pragma once
 2
 3 #include "CSocketProtocol.h"
 4
 5 class CSckImp1 : public CSocketProtocol
 6 {
 7 public:
 8     //无参构造函数
 9     CSckImp1();
10
11     //拷贝构造函数
12     CSckImp1(const CSckImp1 &csk);
13
14     //析构函数
15     ~CSckImp1();
16
17     //赋值运算符重载
18     CSckImp1 &operator=(const CSckImp1 &csk);
19
20     //初始化句柄
21     virtual int Init_Socket();
22
23     //发送报文
24     virtual int Send_Socket(const unsigned char *buf, int bufLen);
25
26     //接收报文
27     virtual int Recv_Socket(unsigned char *buf, int *bufLen);
28
29     //销毁句柄
30     virtual int Destroy_Socket();
31 private:
32     char *data;
33     int dataLen;
34 };

CSckImp1.h

文件:CSckImp1.cpp

 1 #include "CSckImp1.h"
 2
 3 //无参构造函数
 4 CSckImp1::CSckImp1()
 5 {
 6     data = NULL;
 7     dataLen = 0;
 8 }
 9
10 //拷贝构造函数
11 CSckImp1::CSckImp1(const CSckImp1 &csk)
12 {
13     dataLen = csk.dataLen;
14     data = new char[csk.dataLen];
15     memcpy(data, csk.data, dataLen);
16 }
17
18 //析构函数
19 CSckImp1::~CSckImp1()
20 {
21     if (data != NULL)
22     {
23         delete[] data;
24         data = NULL;
25         dataLen = 0;
26     }
27 }
28
29 //赋值运算符重载
30 CSckImp1 &CSckImp1::operator=(const CSckImp1 &csk)
31 {
32     if (data != NULL)
33     {
34         delete[] data;
35         data = NULL;
36     }
37     dataLen = csk.dataLen;
38     data = new char[csk.dataLen];
39     memcpy(data, csk.data, dataLen);
40     return *this;
41 }
42
43 //初始化句柄
44 int CSckImp1::Init_Socket()
45 {
46     if (data != NULL)
47     {
48         delete[] data;
49         data = NULL;
50         dataLen = 0;
51     }
52     return 0;
53 }
54
55 //发送报文
56 int CSckImp1::Send_Socket(const unsigned char *buf, int bufLen)
57 {
58     if (data != NULL)
59     {
60         delete[] data;
61         data = NULL;
62     }
63     dataLen = bufLen;
64     data = new char[dataLen];
65     memcpy(data, buf, dataLen);
66     return 0;
67 }
68
69 //接收报文
70 int CSckImp1::Recv_Socket(unsigned char *buf, int *bufLen)
71 {
72     memcpy(buf, data, dataLen);
73     *bufLen = dataLen;
74     return 0;
75 }
76
77 //销毁句柄
78 int CSckImp1::Destroy_Socket()
79 {
80     if (data != NULL)
81     {
82         delete[] data;
83         data = NULL;
84         dataLen = 0;
85     }
86     return 0;
87 }

CSckImp1.cpp

集成测试main函数

文件:main.cpp

 1 #include <string.h>
 2 #include "CSckImp1.h"
 3
 4 void FrameWork(CSocketProtocol *csp, unsigned char *inBuf, int inBufLen, unsigned char *outBuf, int *outBufLen)
 5 {
 6     csp->Init_Socket();
 7     csp->Send_Socket(inBuf, inBufLen);
 8     csp->Recv_Socket(outBuf, outBufLen);
 9     csp->Destroy_Socket();
10 }
11
12 void TestFrameWork(void)
13 {
14     //待发送的报文
15     unsigned char inBuf[1024] = "We never konw what will happen in the future.";
16     int inBufLen = strlen((char *)inBuf) + 1;
17
18     //存放接收到的报文
19     unsigned char outBuf[1024];
20     int outBufLen = 0;
21
22     //实例化接口
23     CSckImp1 csk;
24
25     //通信业务
26     FrameWork(&csk, inBuf, inBufLen, outBuf, &outBufLen);
27
28     //打印接收到的报文
29     cout << "报文长度为: " << outBufLen << endl;
30     cout << "报文内容为: " << outBuf << endl;
31 }
32
33 int main(void)
34 {
35     TestFrameWork();
36     return 0;
37 }

main.cpp

时间: 2024-10-05 05:21:54

C面向接口编程和C++多态案例的相关文章

面向接口编程详解(一)——思想基础

我想,对于各位使用面向对象编程语言的程序员来说,“接口”这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到“面向接口编程”这个短语,那么它是什么意思?有什么思想内涵?和面向对象编程是什么关系?本文将一一解答这些疑问. 1.面向接口编程和面向对象编程是什么关系 首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分.或者说,

C#面向接口编程详解(1)——思想基础

我想,对于各位使用面向对象编程语言的程序员来说,"接口"这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到"面向接口编程"这个短语,那么它是什么意思?有什么思想内涵?和面向对象编程是什么关系?本文将一一解答这些疑问. 1.面向接口编程和面向对象编程是什么关系 首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思

面向接口编程详解

一:思想基础 我想,对于各位使用面向对象编程语言的程序员来说,"接口"这个名词一定不陌生,但是不知各位有没有这样的疑惑:接口有什么用途?它和抽象类有什么区别?能不能用抽象类代替接口呢?而且,作为程序员,一定经常听到"面向接口编程"这个短语,那么它是什么意思?有什么思想内涵?和面向对象编程是什么关系?本文将一一解答这些疑问. 1.面向接口编程和面向对象编程是什么关系 首先,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附

【设计模式】设计原则--面向接口编程你理解的对吗?

最近看了<Head First Design Patterns>这本书.正如其名,这本书讲的是设计模式(Design Patterns),而这本书的第一章,讲的是很重要的一些设计原则(Design Principles). Identify the aspects of your application that vary and separate them from what stays the same.(识别应用程序中各个方面的变化,并将它们与保持不变的部分分开.) Program to

面向接口编程详解(二)——编程实例

通过上一篇文章的讨论,我想各位朋友对“面接接口编程”有了一个大致的了解.那么在这一篇里,我们用一个例子,让各位对这个重要的编程思想有个直观的印象.为充分考虑到初学者,所以这个例子非常简单,望各位高手见谅. 问题的提出 定义:现在我们要开发一个应用,模拟移动存储设备的读写,即计算机与U盘.MP3.移动硬盘等设备进行数据交换. 上下文(环境):已知要实现U盘.MP3播放器.移动硬盘三种移动存储设备,要求计算机能同这三种设备进行数据交换,并且以后可能会有新的第三方的移动存储设备,所以计算机必须有扩展性

面向接口编程详解(三)——模式研究

通过前面两篇,我想各位朋友对“面向接口编程”的思想有了一定认识,并通过第二篇的例子,获得了一定的直观印象.但是,第二篇中的例子旨在展示面向接口编程的实现方法,比较简单,不能体现出面向接口编程的优势和这种思想的内涵.那么,这一篇作为本系列的终结篇,将通过分析几个比较有深度的模式或架构,解析隐藏其背后的面向接口思想.这篇我将要分析的分别是MVC模式和.NET平台的分层架构. 这篇的内容可能会比较抽象,望谅解. 1.从MVC开始 MVC简介: 本文不打算详细解释MVC架构,而是把重点放在其中的面向接口

多态案例

多态案例 例一 . class Test1Demo { .         public static void main(String[] args) { .             Fu f = new Zi(); . //f.method(); //编译看左边,运行看右边,左边没有method方法,报错, .             f.show();//编译看左边,运行看右边,父类有show,编译没问题,输出Zishow,如果Zi类没有show方法,则运行时发现子类没有去重写,则直接调用

[Chrome]关于面向接口编程的应用

面向接口编程是OOP中有效隔离变化的手段,同时要求开发者必须对问题进行有效抽象.Chrome为了兼容AOSP WebView和Chromium Android WebView, 在实现中做了许多的抽象,充分做到了上层只依赖于接口的原则(依赖倒置),可以有效的兼容不同的WebView实现,隔离其内部的变化. 下面即为WebView到Content层的分解.刚开始读Chrome的代码,还没有细致整理,以后慢慢完善. WebViewFactory是一个顶层类(单例),WebView就是通过它来获取不同

什么叫面向接口编程以及面向接口编程的好处

http://www.cnblogs.com/xyqCreator/archive/2012/11/06/2756687.html 在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的.在这种情况下,各个对象内部是如何实现自己的对系统设计人员来讲就 不那么重要了:而各个对象之间的协作关系则成为系统设计的关键.小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系 统设计的主要工作内容.面向接口编程我想就是指按照这种思想来编程吧!实际上,在日常工作中