博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
os2ip及i2osp的实现
阅读量:2220 次
发布时间:2019-05-08

本文共 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);
}
//#endif

 

int 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_MPMULTWO
int 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/

你可能感兴趣的文章
一文了解强化学习
查看>>
CART 分类与回归树
查看>>
seq2seq 的 keras 实现
查看>>
seq2seq 入门
查看>>
什么是 Dropout
查看>>
用 LSTM 做时间序列预测的一个小例子
查看>>
用 LSTM 来做一个分类小问题
查看>>
详解 LSTM
查看>>
按时间轴简述九大卷积神经网络
查看>>
详解循环神经网络(Recurrent Neural Network)
查看>>
为什么要用交叉验证
查看>>
用学习曲线 learning curve 来判别过拟合问题
查看>>
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>