我的密码给我一个浮点例外,我不知道为什么?

时间:2014-04-17 18:11:10

标签: c encryption

嘿所以,我是新的程序员,我正在大学学习基础C课程,我们分配了一个实现她给我们的算法的项目,它使用线性会员生成器(LCG)来加密和解密输入。她给了我们一个非常详细的大纲或代码模板,但是现在我遇到了浮点异常,我猜它涉及我的加密代码,这是最后一种方法之一,但我不确定。我已删除代码模板以缩短此帖子,但可以根据需要发布。

#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* provides EXIT_SUCCESS */
#define DEBUG 0
#define MAP_LENGTH 28

enum cipherModeEnum {ENCRYPT, DECRYPT};
enum cipherModeEnum cipherMode;

/*
The different status codes are flags.
Since each is a power of 2, they can be turned on or off independently.
*/
int status;
const int CLEAR = 0;
const int OK = 1;
const int END_OF_LINE = 2;
const int END_OF_FILE = 4;
const int ERROR = 8;

unsigned long lcg_c;
unsigned long lcg_m;
unsigned long lcg_a;
unsigned long lcg_x;
int cipherMap[MAP_LENGTH];
int countForRPL = 0;
int inputLineNumber = 0;

/* this method will convert a character to a digit */
int charToDigit( char c )
{
  return c - '0';
}

int binToDec( int * binaryArray )
 {
   int value, i;
   value = 0;
   for( i = 0; i <= 8; i++ )
   {
    value = ( value << 1 ) | binaryArray[i];
   }
   return value;
 }


   unsigned long readPositiveLong(char delimiter)
{
  unsigned long digits;
  char c;
  int errorC, count, skipFirstChar;
  errorC = count = skipFirstChar = 0;
  while( c = getchar() )
  {
    if( skipFirstChar == 0 )
    {
      skipFirstChar++;
    }
    else
    {
      count++;
      if( countForRPL == 0 )
      {
        digits = digits * 10 + charToDigit(c);
        if( c == delimiter )
        {
          countForRPL == 1;
          break;
        }
      }
      else
      {
        if( c == delimiter )
        {
          countForRPL = 0;
        }
      }
      if( c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && c != '5' &&
          c != '6' && c != '7' && c != '8' && c != '9' && c != delimiter)
      {
        errorC = 1;
        break;
      }
      if( count > 20 )
      {
        errorC = 1;
      }
    }
  }
  if( errorC == 0 )
  {
    return digits;
  }
  else
  {
    return 0;
  }
}
int setUniquePrimeFactors(unsigned long n, int prime[], int maxPrimes)
{
  int i, count;
  count = 0;
  for( i = 2; n > 1; i++ )
  {
    if( n % i == 0 )
    {
      while( n % i == 0 )
      {
        n /= i;
      }
      prime[count] = i;
      count++;
    }
  }
  if( count >= maxPrimes )
  {
    return 0;
  }
  else
  {
    return count;
  }
}
unsigned long calculateLCG_a(unsigned long LCG_m)
{
  int prime[64] = { };
  unsigned long a, p;
  int i, count;
  a = p = count = 0;
  count = setUniquePrimeFactors(LCG_m, prime, 64);
  if( count = 0 )
  {
    return 0;
  }
  for( i = 0; i < count; i++ )
  {
    p = p * prime[i];
  }
  if( LCG_m % 4 == 0 )
  {
    a = 1+2*p;
  }
  else
  {
    a = 1+p;
  }
  if( a > 0 && a < LCG_m )
  {
    return a;
  }
  else
  {
    return 0;
  }
}
void skipToEndOfLine(void)
{
  char c;
  while( c = getchar() )
  {
    if( c == '\n' )
    {
      status = END_OF_LINE;
      break;
    }
    if( c == EOF )
    {
      status = END_OF_FILE;
      break;
    }
  }
}
int readDataBlock(char data[])
{
  char c, twoByteChange;
  twoByteChange = '?';
  int place, dataSize, findData, count;
  place = dataSize = findData = count = 0;
  while( c = getchar() )
  {
    if( c == ',' )
    {
      findData++;
    }
    if( findData == 2 )
    {
      if( c == '\n' )
      {
        if( dataSize < 4 && dataSize > 0 )
        {
          int pad;
          for( pad = 0; pad < (5-dataSize); pad++ )
          {
            data[place] = '\0';
            place++;
          }
        }
        return END_OF_LINE;
      }
      if( c == EOF )
      {
        return END_OF_FILE;
      }
      if( cipherMode == ENCRYPT )
      {
        data[place] = c;
        place++;
        dataSize++;
      }
      if( cipherMode == DECRYPT )
      {
        if( count == 1 )
        {
          data[place] = c & twoByteChange;
          count = 0;
          place++;
          dataSize++;
        }
        if( c == '+' )
        {
          count = 1;
        }
        if( count = 0 )
        {
          data[place] = c;
          place++;
          dataSize++;
        }
      }
    }
  }
  return OK;
}
int readCipherMode(void)
{
  char c;
  c = getchar();
  if( c == 'e' )
  {
    cipherMode = ENCRYPT;
    return OK;
  }
  else if( c == 'd' )
  {
    cipherMode = DECRYPT;
    return OK;
  }
  else if( c == '\n' )
  {
    return END_OF_LINE;
  }
  else if( c == EOF )
  {
    return END_OF_FILE;
  }
  else
  {
    return ERROR;
  }
}
void buildMap(void)
{
  int count, countDown, i, used, usedCount;
  count = usedCount = 0;
  int g[MAP_LENGTH] = { };
  char free[28] =    {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19,20,21,22,23,24,25,26,27};
  for( i = 0; i < 28; i++ )
  {
    countDown = 28 - i;
    if( count == 0 )
    {
      lcg_x = lcg_m;
      g[i] = lcg_x % countDown;
      count = 1;
    }
    else
    {
      lcg_x = (( lcg_a * lcg_x + lcg_c ) % lcg_m );
      g[i] =  lcg_x % countDown;
    }
  }
  for( i = 0; i < 28; i++ )
  {
    for( used = 0; used < g[i]; used++ )
    {
      if( free[used] == 'u' )
        {
          usedCount++;
        }
    }
      cipherMap[i] = free[g[i]] + usedCount;
      free[g[i]] = 'u';
  }
}
int encrypt(char data[])
{
  int i, remainder, place;
  place = 0;
  char input = data[place];
  char binary[3] = "01";
  char digitsArray[28] = { };
  char binaryOutput[28] = { };
  int partOne[8] = { };
  int partTwo[8] = { };
  int partThree[8] = { };
  int partFour[8] = { };
  char output[8] = { };
  for( i = 7; i > 0; i-- )
  {
    remainder = input % 2;
    input = input/2;
    digitsArray[7-i] = binary[remainder];
  }
  place++;
  for( i = 14; i > 7; i-- )
  {
    remainder = input % 2;
    input = input/2;
    digitsArray[7-i] = binary[remainder];
  }
  place++;
  for( i = 20; i > 14; i-- )
  {
    remainder = input % 2;
    input = input/2;
    digitsArray[7-i] = binary[remainder];
  }
  place++;
  for( i = 27; i > 20; i-- )
  {
    remainder = input % 2;
    input = input/2;
    digitsArray[7-i] = binary[remainder];
  }
  for( i = 0; i < 28; i++ )
  {
    binaryOutput[cipherMap[i]] = digitsArray[i];
  }
  for( i = 7; i > 0; i-- )
  {
    partOne[i-1] = binaryOutput[7-i];
  }
  partOne[7] = '0';
  for( i = 14; i > 7; i-- )
  {
    partTwo[i-8] = binaryOutput[14-i];
  }
  partTwo[7] = '0';
  for( i = 20; i > 14; i-- )
  {
    partThree[i-15] = binaryOutput[20-i];
  }
  partThree[7] = '0';
  for( i = 27; i > 20; i-- )
  {
     partFour[i-21] = binaryOutput[27-i];
  }
  partFour[7] = '0';
  output[0] = binToDec(partOne);
  output[1] = binToDec(partTwo);
  output[2] = binToDec(partThree);
  output[3] = binToDec(partFour);
  printf("%5d) %s\n", inputLineNumber, output);
}
int main()
{

  int inputLineNumber = 0;
  status = CLEAR;

  char data[5];
  data[4] = '\0';

  while (status != END_OF_FILE)
  {
    status = CLEAR;
    inputLineNumber++;

    status = readCipherMode();

    if (DEBUG) printf("readCipherMode::mode=%d status=%d\n",cipherMode,status);

    if ((status & END_OF_FILE) == 0)
    {
      printf("%5d) ", inputLineNumber);
    }
    if (status == OK)
    {
      status = readKey();
      if (DEBUG)
    {
      printf ("\tKey: m=%lu c=%lu a=%lu x=%lu status=%d\n",
               lcg_m, lcg_c, lcg_a, lcg_x, status);
     }
    }

    while (status == OK)
    {
      buildMap();
      status = readDataBlock(data);
      if (DEBUG) printf("\treadDataBlock::data=%s status=%d\n",data,status);
      if ((status & ERROR) == 0)
      {
        if (cipherMode == ENCRYPT) status |= encrypt(data);
        else status |= decrypt(data);
      }
   }

    if (status & ERROR)
    {
      puts("Error");
      skipToEndOfLine();
    }
    else puts("");
 }
 return EXIT_SUCCESS;

}

我还没有创建或启动解密代码,因为我不知道为什么我的加密代码不起作用,我知道它看起来不是很好但是这是我能想到的最好的,我的编码知识。

1 个答案:

答案 0 :(得分:0)

您尝试通过long除以后检查余数来找到int的素数因子。您的号码是素数,因此您无法将其除以正常int s范围内的任何数字,通常为-2147483648至2147483647.当您达到最大值时,您的增量{{1包裹(如里程表)到最小值,最终最终为零。砰!您应该将本地i++设为i

这会给你带来另一个问题:对于非素数和小素数,你的素因子化是可以的。这将需要完整的7818741776187847循环才能将unsigned long降低到1.(您可以通过乐观地假设一个非常快的处理器可以在一秒内处理1G循环来粗略估计乐趣。您的因子分析将需要大约90天。)

为了迎合这种边缘情况,你可以先进行素性检查:

n

这不快,但可以在有限的时间内完成。

顺便说一下,如何处理数组大小int is_prime(unsigned long n) { unsigned long m; if (n % 2 == 0) return 0; for (m = 3; m*m <= n; m+= 2) { if (n % m == 0) return 0; } return 1; } 时出错:当您检查此数组绑定时,您已经填充了数组,可能会溢出缓冲区maxPrimes。在增加prime后,应检查循环中的缓冲区大小。