本文共 5609 字,大约阅读时间需要 18 分钟。
.h文件
#ifndef _MP_H
#define _MP_H #define _REENTRANT#include <stdlib.h>
#include <string.h>typedef unsigned char uint8_t;
typedef unsigned short uint16_t;typedef unsigned int uint32_t;#define MP_WBITS 32U
typedef uint8_t byte;
typedef uint32_t mpw;typedef uint16_t mphw; #define MP_HWBITS (MP_WBITS >> 1)#define MP_WBYTES (MP_WBITS >> 3)#define MP_WNIBBLES (MP_WBITS >> 2) # define MP_WORDS_TO_BITS(x) ((x) << 5)# define MP_WORDS_TO_NIBBLES(x) ((x) << 3)# define MP_WORDS_TO_BYTES(x) ((x) << 2)# define MP_BITS_TO_WORDS(x) ((x) >> 5) # define MP_NIBBLES_TO_WORDS(x) ((x) >> 3)# define MP_BYTES_TO_WORDS(x) ((x) >> 2)
#define MP_MSBMASK (((mpw) 0x1) << (MP_WBITS-1))
#define MP_LSBMASK ((mpw) 0x1)#define MP_ALLMASK ~((mpw) 0x0)#ifdef __cplusplus
extern "C" { #endif /*!/fn void mpzero(size_t size, mpw* data) * /brief This function zeroes a multi-precision integer of a given size. * /param size The size of the multi-precision integer. * /param data The multi-precision integer data. */void mpzero(size_t size, mpw* data);
/*!/fn void mpsetw(size_t size, mpw* xdata, mpw y) * /brief This function sets the value of a multi-precision integer to the * given word. The given value is copied into the least significant word, * while the most significant words are zeroed. * /param size The size of the multi-precision integer. * /param xdata The first multi-precision integer. * /param y The multi-precision word. */void mpsetw(size_t size, mpw* xdata, mpw y);
int mpmultwo(size_t size, mpw* data);
/* * Conversion Routines */ int os2ip(mpw* idata, size_t isize, const byte* osdata, size_t ossize); int i2osp(byte* osdata, size_t ossize, const mpw* idata, size_t isize);
#ifdef __cplusplus
}#endif#endif
.c 文件
#include "O_I.h"
//#ifndef ASM_MPZERO
void mpzero(size_t size, mpw* data){ while (size--) *(data++) = 0;}//#endif//#ifndef ASM_MPMSZCNT
size_t mpmszcnt(size_t size, const mpw* data){ register size_t zbits = 0; register size_t i = 0;while (i < size)
{ register mpw temp = data[i++]; if (temp) { while (!(temp & MP_MSBMASK)) { zbits++; temp <<= 1; } break; } else zbits += MP_WBITS; } return zbits;}//#endif//#ifndef ASM_MPBITS
size_t mpbits(size_t size, const mpw* data){ return MP_WORDS_TO_BITS(size) - mpmszcnt(size, data); }//#endifint i2osp(byte *osdata, size_t ossize, const mpw* idata, size_t isize){ #if WORDS_BIGENDIAN size_t max_bytes = MP_WORDS_TO_BYTES(isize); #endif size_t significant_bytes = (mpbits(isize, idata) + 7) >> 3;
/* verify that ossize is large enough to contain the significant bytes */
if (ossize >= significant_bytes) { /* looking good; check if we have more space than significant bytes */ if (ossize > significant_bytes) { /* fill most significant bytes with zero */ memset(osdata, 0, ossize - significant_bytes); osdata += ossize - significant_bytes; } if (significant_bytes) { /* fill remaining bytes with endian-adjusted data */ #if !WORDS_BIGENDIAN mpw w = idata[--isize]; byte shift = 0;/* fill right-to-left; much easier than left-to-right */
do { osdata[--significant_bytes] = (byte)(w >> shift); shift += 8; if (shift == MP_WBITS) { shift = 0; w = idata[--isize]; } } while (significant_bytes); #else /* just copy data past zero bytes */ memcpy(osdata, ((byte*) idata) + (max_bytes - significant_bytes), significant_bytes); #endif } return 0; } return -1;}int os2ip(mpw* idata, size_t isize, const byte* osdata, size_t ossize)
{ size_t required;/* skip non-significant leading zero bytes */
while (!(*osdata) && ossize) { osdata++; ossize--; }required = MP_BYTES_TO_WORDS(ossize + MP_WBYTES - 1);
if (isize >= required)
{ /* yes, we have enough space and can proceed */ mpw w = 0; /* adjust counter so that the loop will start by skipping the proper * amount of leading bytes in the first significant word */ byte b = (ossize % MP_WBYTES);if (isize > required)
{ /* fill initials words with zero */ mpzero(isize-required, idata); idata += isize-required; }if (b == 0)
b = MP_WBYTES;while (ossize--)
{ w <<= 8; w |= *(osdata++); b--;if (b == 0)
{ *(idata++) = w; w = 0; b = MP_WBYTES; } }return 0;
} return -1;}int hs2ip(mpw* idata, size_t isize, const char* hsdata, size_t hssize)
{ size_t required = MP_NIBBLES_TO_WORDS(hssize + MP_WNIBBLES - 1);if (isize >= required)
{ register size_t i; if (isize > required) { /* fill initial words with zero */ for (i = required; i < isize; i++) *(idata++) = 0; } while (hssize) { register mpw w = 0; register size_t chunk = hssize & (MP_WNIBBLES - 1); register char ch;if (chunk == 0) chunk = MP_WNIBBLES;
for (i = 0; i < chunk; i++)
{ ch = *(hsdata++); w <<= 4; if (ch >= '0' && ch <= '9') w += (ch - '0'); else if (ch >= 'A' && ch <= 'F') w += (ch - 'A') + 10; else if (ch >= 'a' && ch <= 'f') w += (ch - 'a') + 10; } *(idata++) = w; hssize -= chunk; } return 0; } return -1;} //#ifndef ASM_MPMULTWOint mpmultwo(size_t size, mpw* data){ register mpw temp, carry = 0;data += size;
while (size--) { temp = *(--data); *data = (temp << 1) | carry; carry = (temp >> (MP_WBITS-1)); } return (int) carry;}//#endif//#ifndef ASM_MPSETW
void mpsetw(size_t size, mpw* xdata, mpw y){ while (--size) *(xdata++) = 0; *(xdata++) = y;}//#endif
测试文件:
#include <stdio.h>
#include "O_I.h"void hexdump(byte* b, int count)
{ int i;for (i = 0; i < count; i++)
{ printf("%02x", b[i]); if ((i & 0xf) == 0xf) printf("/n"); } if (i & 0xf) printf("/n");}int main()
{ int rc; mpw x[4]; byte o[9];mpsetw(4, x, 255);
mpmultwo(4, x); rc = i2osp(o, 9, x, 4);printf("rc = %d/n", rc);
hexdump(o, 9);rc = os2ip(x, 4, o, 9);
printf("rc = %d/n", rc); //mpprintln(4, x);while(1);
exit(0); return 0;}转载地址:http://hpnfb.baihongyu.com/