嘿所以,我是新的程序员,我正在大学学习基础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;
}
我还没有创建或启动解密代码,因为我不知道为什么我的加密代码不起作用,我知道它看起来不是很好但是这是我能想到的最好的,我的编码知识。
答案 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
后,应检查循环中的缓冲区大小。