gpt4 book ai didi

C:对另一个文件中函数的 undefined reference

转载 作者:行者123 更新时间:2023-12-04 05:53:41 25 4
gpt4 key购买 nike

我正在尝试调用在另一个文件中定义的 C 函数。我将函数的定义添加到头文件中,并将其包含在两个 .c 文件中,但仍然收到错误消息:

C:\Users\Hunter\AppData\Local\Temp\ccyqsulH.o:

In function main':
C:DES_hash.c:42: undefined reference to
DES'

collect2: ld returned 1 exit status



这是函数原型(prototype)定义:
/* DES_Utils.h */
#ifndef GUARD_DES_Utils /* prevents errors when including twice */
#define GUARD_DES_Utils

#include "DES.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned long long * DES(unsigned long long, unsigned long long);
....
#endif

这里是定义函数的地方:
/* DES.c */
#include "DES_Utils.h"
unsigned long long * DES(unsigned long long plaintext, unsigned long long key)
{
.....
}

这是我尝试使用它的地方:
/* DES_hash.c */
#include "DES_Utils.h"
int main(int argc, int * argv)
{
.....
Ekp_i = DES(P_i ^ C_i, k); //<- line 42
..... //P_i, C_i, and k are all unsigned long longs
}

编辑:完整源代码(有点大,抱歉)

DES.h:
 #ifndef GUARD_DES /* prevents errors when including twice */
#define GUARD_DES

#define NUM_ROUNDS 16
/* 1. Data Encoding Permutations and Definitions */

/* This macro defines the initial permutation, it will re-order the
64-bit message into this bit configuration
Source: Stallings pg 80
Note: all indices in this macro are 1 less than the table in Stallings
because arrays are 0-based in C
*/
#define IP(x) { x[57], x[49], x[41], x[33], x[25], x[17], x[9], x[1], \
x[59], x[51], x[43], x[35], x[27], x[19], x[11], x[3], \
x[61], x[53], x[45], x[37], x[29], x[21], x[13], x[5], \
x[63], x[55], x[47], x[39], x[31], x[23], x[15], x[7], \
x[56], x[48], x[40], x[32], x[24], x[16], x[8], x[0], \
x[58], x[50], x[42], x[34], x[26], x[18], x[10], x[2], \
x[60], x[52], x[44], x[36], x[28], x[20], x[12], x[4], \
x[62], x[54], x[46], x[38], x[30], x[22], x[14], x[6] }

/* This macro defines the final permutation
Note: all numbers are off by 1 to support 0-based array indexing*/
#define IP_1(x) {
x[39], x[7], x[47], x[15], x[55], x[23], x[63], x[31], \
x[38], x[6], x[46], x[14], x[54], x[22], x[62], x[30], \
x[37], x[5], x[45], x[13], x[53], x[21], x[61], x[29], \
x[36], x[4], x[44], x[12], x[52], x[20], x[60], x[28], \
x[35], x[3], x[43], x[11], x[51], x[19], x[59], x[27], \
x[34], x[2], x[42], x[10], x[50], x[18], x[58], x[26], \
x[33], x[1], x[41], x[9], x[49], x[17], x[57], x[25], \
x[32], x[0], x[40], x[8], x[48], x[16], x[56], x[24]}

/* This macro defines the expansion permutation, it takes an input of
32 bits; reorders these bits and reuses some bits in places,
producing a 48-bit output
Note: all numbers are off by 1 to support 0-based array indexing */
#define E(x) { x[31], x[0], x[1], x[2], x[3], x[4], \
x[3], x[4], x[5], x[6], x[7], x[8], \
x[7], x[8], x[9], x[10], x[11], x[12], \
x[11], x[12], x[13], x[14], x[15], x[16], \
x[15], x[16], x[17], x[18], x[19], x[20], \
x[19], x[20], x[21], x[22], x[23], x[24], \
x[23], x[24], x[25], x[26], x[27], x[28], \
x[27], x[28], x[29], x[30], x[31], x[0] }

/* This macro defines the Permutation function P which shuffles a 32
bit array
Note: all numbers are off by 1 to support 0-based array indexing */
#define P(x) { x[15], x[6], x[19], x[20], \
x[28], x[11], x[27], x[16], \
x[0], x[14], x[22], x[25], \
x[4], x[17], x[30], x[9], \
x[1], x[7], x[23], x[13], \
x[31], x[26], x[2], x[8], \
x[18], x[12], x[29], x[5], \
x[21], x[10], x[3], x[24]}

/* These Matrix definitions are for the S boxes */
#define SBOX_ROWS 4
#define SBOX_COLS 16

int SBOX_1[SBOX_ROWS][SBOX_COLS] = {
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}};

int SBOX_2[SBOX_ROWS][SBOX_COLS] = {
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}};

int SBOX_3[SBOX_ROWS][SBOX_COLS] = {
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}};

int SBOX_4[SBOX_ROWS][SBOX_COLS] = {
{ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}};

int SBOX_5[SBOX_ROWS][SBOX_COLS] = {
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}};

int SBOX_6[SBOX_ROWS][SBOX_COLS] = {
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}};

int SBOX_7[SBOX_ROWS][SBOX_COLS] = {
{ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}};

int SBOX_8[SBOX_ROWS][SBOX_COLS] = {
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};


/* 2. Subkey Generation Permutations and Definitions*/

/* This macro defines Permuted Choice#1, it reorders and reduces the input
64-bit key to 56 bits, Note: all numbers are off by
1 to support 0-based array indexing */
#define PC_1(x) { x[56], x[48], x[40], x[32], x[24], x[16], x[8], \
x[0], x[57], x[49], x[41], x[33], x[25], x[17], \
x[9], x[1], x[58], x[50], x[42], x[34], x[26], \
x[18], x[10], x[2], x[59], x[51], x[43], x[35], \
x[62], x[54], x[46], x[38], x[30], x[22], x[14], \
x[6], x[61], x[53], x[45], x[37], x[29], x[21], \
x[13], x[5], x[60], x[52], x[44], x[36], x[28], \
x[20], x[12], x[4], x[27], x[19], x[11], x[3] }

/* This macro defines Permuted Choice#2, it reorders and reduces the input
56-bit key to 48 bits
Note: all numbers are off by 1 to support 0-based array indexing */
#define PC_2(x) { x[13], x[16], x[10], x[23], x[0], x[4], \
x[2], x[27], x[14], x[5], x[20], x[9], \
x[22], x[18], x[11], x[3], x[25], x[7], \
x[15], x[6], x[26], x[19], x[12], x[1], \
x[40], x[51], x[30], x[36], x[46], x[54], \
x[29], x[39], x[50], x[44], x[32], x[47], \
x[43], x[48], x[38], x[55], x[33], x[52], \
x[45], x[41], x[49], x[35], x[28], x[31] }

/* This array defines the number of left shifts to perform
at round i */
#define NUM_LEFTSHIFTS 16
int LEFTSHIFT_SCHEDULE[NUM_LEFTSHIFTS] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
#endif

DES_Utils.h:
/* McMillen_DES_Utils.h
* This header file holds the functions that do
* the majority of the work for my program. I abstracted
* them from the main C file to avoid excess clutter
*
* Hunter McMillen
* 2/9/2012
*/
#ifndef GUARD_DES_Utils /* prevents errors when including twice */
#define GUARD_DES_Utils


#include "DES.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//Definition of shared function !!
unsigned long long * DES(unsigned long long plaintext, unsigned long long key);

/* Counts the number of bits it
* takes to represent an integer a
*/
int num_bits(unsigned long long a)
{
int bitCount = 0;

while(a > 0)
{
bitCount++;
a = a >> 1; //shift to the right 1 bit
}

return bitCount;
}

/* Converts from an unsigned long long into an array of
integers that form the binary representation of a */
void ull_to_bin_array(unsigned long long a, int *b, int length)
{
int *temp = malloc(length * sizeof(int));

int i;
for(i = length - 1; i >= 0; i--)
{
temp[i] = (a >> i) & 1; //store the ith bit in temp[i]
}

for(i = 0; i < length; i++)
{
int tLen = (length - 1) - i; //mapping from temp[i] -> b[i]
b[i] = temp[tLen];
//store the (length - i)th of temp in b[i], this puts the MSB first
}
}

unsigned long long * bin_string_to_ull(char * bin_string)
{
//allocate space for a pointe to an ull
unsigned long long * out = malloc(sizeof(unsigned long long));
//interpret bin_string as a 64-bit number
unsigned long long t = strtoull(bin_string, NULL, 2);

//copy the address of t into out
out = &t;

return out;
}

/* prints a one-dimensional array given
a pointer to it, and its length, and optionally a header */
void print_array(int *arr, int length, char *msg)
{
int i;
if(msg != NULL) printf("%s: ",msg);
for(i = 0; i < length; i++)
{
printf("%d", arr[i]);
}
printf("\n");
}

/**
* Takes an input of a 4 element character array
* that represents a half-byte in binary, maps
* the 4-bit value to the appropriate hex character
*/
void map_bin_to_hex(char *c)
{
char hexMap[] = "0123456789ABCDEF";
int index = strtoull(c, NULL, 2);
printf("%c", hexMap[index]);
}

/**
* Takes a 64 element integer array that holds
* the binary representation of a 64-bit hex number
*/
void bin_array_to_hex(int *b, int length)
{
int i, j, k;

//read 4 bits 16 times
for(i = 0; i < length; i+=4)
{
char hexB[5];
for(k = 0, j = i; j < (i+4); j++, k++)
{
hexB[k] = b[j] + '0';
//printf("h[%d] = %d\n", k, hexB[k]);
}
hexB[5] = '\0';
map_bin_to_hex(hexB);
}
printf("\n");
}

/**
* Takes as input an integer array containing the binary
* representation of some number N, and converts all the
* bits of N to characters then compresses
* them into a single "string"
*/
char * bin_array_to_string(int *b, int length)
{
//allocate space for length characters
char *string = malloc((length+1) * sizeof(char));

int i;
for(i = 0; i < length; i++)
{
string[i] = b[i] + '0';
}
string[length] = '\0';

return string;
}

/**
* This function takes as input the binary representation
* of a 64-bit integer held in array form, and partitions it
* into LEFT and RIGHT halves
*/
void partition_arrays(int *s, int *l, int *r, int length)
{
int pLength = length / 2;
int i, j;

for(i = 0; i < pLength; i++)
{
l[i] = s[i];
}

for(i = pLength, j = 0; i < length - 1; i++, j++)
{
r[j] = s[i];
}
}

/**
* Takes two arrays of equals length and concatenates their
* contents using memcpy
*/
int * concatenate_arrays(int *a, int *b, int length)
{
int aLen = length * sizeof(int);
int bLen = length * sizeof(int);
//allocate enough space in the new array for both arrays a and b
int *new = malloc((aLen + bLen) * sizeof(int));

memcpy(new, a, aLen);
memcpy(new + length, b, bLen);

return new;
}

/**
* Given an integer array and a character array, this function
* converts the character array to an integer then XORs the two arrays
* contents
*/
int * xor_arrays(int *a, char *b, int length)
{
//alocate enough space in the xor array
int *xor = malloc(length * sizeof(int));

int i;
for(i = 0; i < length; i++)
{
xor[i] = a[i] ^ (b[i] - '0');
//compute xor, subtract '0' to convert from char to int
}

return xor;
}

/**
* Same as the above function but for two integer arrays,
* their contents are XORed and returned in another array
*/
int * xor_int_arrays(int *a, int *b, int length)
{
//alocate enough space in the xor array
int *xor = malloc(length * sizeof(int));

int i;
for(i = 0; i < length; i++)
{
xor[i] = a[i] ^ b[i]; //compute xor
}

return xor;
}

/**
* Given an array and its length, this function will compute
* the results of ALL of the SBOXs for this array
* The result that is returned is an integer array consisting
* of the results from the SBOXs
*/
int * compute_sbox(int *a, int length)
{
/* bits needed for each sbox */
int sbox_length = length / 8;
/* holds integer values retrieved from the SBOX */
int sbox_results[8];
/* two indices for each sbox */
int *sbox_indices = malloc(sbox_length * sizeof(int));

/* i counts every 6 bits in the array
k processes bits from 0 - 6 in the inner loop
j is used to copy values properly into the sbox char array
y indicates what SBOX we are taking a value from */
int i, k, j, y;

/* read 6 bits 8 times */
for(i = 0, y = 0; i < length; i += sbox_length, y++)
{
char sbox[7];
/* grab every 6 elements of the array */
for(k = 0, j = i; j < (i + sbox_length); k++, j++)
{
sbox[k] = a[j] + '0'; //convert to a string
}
sbox[7] = '\0'; //append the null terminator

/* compute the row and column index */
char rows[3];
rows[0] = sbox[0];
rows[1] = sbox[5];
rows[2] = '\0';

char cols[5];
cols[0] = sbox[1];
cols[1] = sbox[2];
cols[2] = sbox[3];
cols[3] = sbox[4];
cols[4] = '\0';

/* get indices into the SBOXy+1 */
int row = strtoull(rows, NULL, 2);
int col = strtoull(cols, NULL, 2);

/* switch over y and get the results from the SBOXs */
switch(y)
{
case 0:
sbox_results[y] = SBOX_1[row][col];
break;
case 1:
sbox_results[y] = SBOX_2[row][col];
break;
case 2:
sbox_results[y] = SBOX_3[row][col];
break;
case 3:
sbox_results[y] = SBOX_4[row][col];
break;
case 4:
sbox_results[y] = SBOX_5[row][col];
break;
case 5:
sbox_results[y] = SBOX_6[row][col];
break;
case 6:
sbox_results[y] = SBOX_7[row][col];
break;
case 7:
sbox_results[y] = SBOX_8[row][col];
break;
default:
break;
}
}

/* at this point we have processed every 6 bits in the array
and retrieved the correct values from the SBOXs,
all that remains is to convert the
results to arrays and concatenate them */

/* initialize arrays */
int SBOX_1_Result[4]; int SBOX_5_Result[4];
int SBOX_2_Result[4]; int SBOX_6_Result[4];
int SBOX_3_Result[4]; int SBOX_7_Result[4];
int SBOX_4_Result[4]; int SBOX_8_Result[4];

/* fill the arrays */
ull_to_bin_array(sbox_results[0], SBOX_1_Result, 4);
ull_to_bin_array(sbox_results[1], SBOX_2_Result, 4);
ull_to_bin_array(sbox_results[2], SBOX_3_Result, 4);
ull_to_bin_array(sbox_results[3], SBOX_4_Result, 4);
ull_to_bin_array(sbox_results[4], SBOX_5_Result, 4);
ull_to_bin_array(sbox_results[5], SBOX_6_Result, 4);
ull_to_bin_array(sbox_results[6], SBOX_7_Result, 4);
ull_to_bin_array(sbox_results[7], SBOX_8_Result, 4);

/* concatenate the arrays in pairs, since my concatenate function above
requires equal length inputs */
int *first_2 = concatenate_arrays(SBOX_1_Result, SBOX_2_Result, 4);
int *second_2 = concatenate_arrays(SBOX_3_Result, SBOX_4_Result, 4);
int *third_2 = concatenate_arrays(SBOX_5_Result, SBOX_6_Result, 4);
int *last_2 = concatenate_arrays(SBOX_7_Result, SBOX_8_Result, 4);

/* combine the two halves */
int *first_half = concatenate_arrays(first_2, second_2, 8);
int *second_half = concatenate_arrays(third_2, last_2, 8);

/* combine into one full array */
int *full = concatenate_arrays(first_half, second_half, 16);

return full;
}

/* Reverses the elements in array a
from index start to end */
void reverse(int *a, int start, int end)
{
int swap;
while(start < end)
{
swap = a[start];
a[start++] = a[--end];
a[end] = swap;
}
}

/**
* Uses a triple-reversal method of left-shifting
* that is described here:
* http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf
* takes as input, a pointer to an array,
* the length of that array and the amount
* to left shift by
*/
void left_shift(int *a, int aLen, int amt)
{
//left shift a by amt using three reversals
reverse(a, 0, amt);
reverse(a, amt, aLen);
reverse(a, 0, aLen);
}
#endif

DES.c:
 #include "DES.h"
#include "DES_Utils.h"

/* Global Definintions */
char *keys[16]; //array of keys for all 16 rounds

/* This function takes as input the initial 64-bit key
* It generates all 16 subkeys for rounds
* 1 - 16 and stores them in the global keys[] array
*/
void generate_subkeys(int key[])
{
/* uses the macro permutation defined in
McMillen_DES.h to permute the initial key into
a 56-bit key */
int PC1_Key[] = PC_1(key);

//split the permuted PC_1 key into two halves
//C and D using pointer arithmetic
int *C0 = PC1_Key;
int *D0 = PC1_Key + 28;
int i;
for(i = 0; i < NUM_ROUNDS; i++)
{
/* left shift C0 and DO by the amount
indicated in the left shift schedule defined in McMillen_DES.h */
left_shift(C0, 28, LEFTSHIFT_SCHEDULE[i]);
left_shift(D0, 28, LEFTSHIFT_SCHEDULE[i]);

/* merge the shifted Ci and Di together,
where i is the round number */
int *temp = concatenate_arrays(C0, D0, 28);

/* pass temp to the Permuted Choice 2 macro,
which will reduce it from 56-bits
to 48-bits and generate Ki, the key for round i */
int Ki[] = PC_2(temp);

/* compress the binary array into a string for storage */
char *keyi = bin_array_to_string(Ki, 48);

/* store the string key for round i */
keys[i] = keyi;
}
}

/**
* This functions handles the encryption functionality
* of the DES algorithm.
*/
void encrypt(int plaintext[])
{
/* permute the plaintext message with the IP */
int permuted_pt[] = IP(plaintext);

/* partition the permuted plaintext into two halves using pointers */
int *Li = permuted_pt;
int *Ri = permuted_pt + 32;

int i;
for(i = 0; i < NUM_ROUNDS; i++)
{
/* pass Ri into the Expansion permutation to
expand it from 32 to 48 bits */
int e_Ri[] = E(Ri);

/* XOR the expanded Ri and Ki, the key for this round i */
int *xorKeyi_Ri = xor_arrays(e_Ri, keys[i], 48);

/* parses the row and column indices from the xor'd key and E(Ri)
then gets the value at that position in SBOXi and concatenates
the results together */
int *sbox = compute_sbox(xorKeyi_Ri, 48);

/* apply the permutation P to the result from the SBOXs */
int permuted_sbox[] = P(sbox);

/* use a temp variable to store Ri, update Ri,
then assign the old Ri to Li */
int *temp = Ri;
Ri = xor_int_arrays(Li, permuted_sbox, 32);
/* Ri = L(i-1) XOR f(R(i-1), Ki) */
Li = temp; /* Li = R(i-1) */
}

/* swap the two halves so Ri comes first */
int *encrypted = concatenate_arrays(Ri, Li, 32);
/* apply the final permutation */
int fp[] = IP_1(encrypted);
/* print the hex result of the final permutation to the console */
bin_array_to_hex(fp, 64);
}

/**
* Encrypts a 64-plaintext value using a 64-bit key
* held as unsigned long long values
*/
unsigned long long * DES(unsigned long long plaintext,
unsigned long long key)
{
/* initialize arrays with 64 positions that will hold the
binary representation of the key and plaintext,
initialized to all 0's */
int key_arr[64] = { 0 };
int pt_arr[64] = { 0 };

/* fill the arrays with the binary representations
of the plaintext and the key */
ull_to_bin_array(key, key_arr, 64);
ull_to_bin_array(plaintext, pt_arr, 64);

/* generate subkeys for all 16 rounds */
generate_subkeys(key_arr);

/* encrypt the plaintext, this function will display the hex results */
encrypt(pt_arr);
}

DES_hash.c:
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DES_Utils.h"

char * strToHex(const char * input);

int main(int argc, int * argv)
{
/* initialize they key and IV (C sub 0)*/
unsigned long long k = strtoull("0123456789ABCDEF", NULL, 16);
unsigned long long C_i = strtoull("00FF11EE22DD33CC", NULL, 16);
unsigned long long P_i;
unsigned long long * Ekp_i;

char buffer[9]; //holds 8 characters read from the file (i.e. 64-bits)
char * plaintext;
FILE *f;

if (f = fopen("input2.txt", "rb"))
{
while( fread(buffer, 8, 1, f) != 0)
{
buffer[8] = '\0';

/* convert the ascii string input into a 64-bit hex string */
plaintext = strToHex(buffer);
/* convert the hex string into a 64 bit unsigned long long value */
P_i = strtoull(plaintext, NULL, 16);

Ekp_i = DES(P_i ^ C_i, k);
C_i = *(Ekp_i);

printf("%s\n", plaintext);
printf("%llu\n", P_i);
printf("%llu\n", C_i);
printf("%llX\n\n", P_i ^ C_i);
break;
}
fclose(f);
}
}

/**
* Converts an array with ascii strings in it
* to its corresponding hex value, this will double
* the size of the input because one ascii character
* is two hex bits
*/
char * strToHex(const char * input)
{
char *output = malloc((strlen(input) * 2) + 1);
char * o = output;

int i;
for (i = 0; input[i] != '\0'; o += 2, i++)
{
sprintf(o, "%02X", input[i]);
}

// don't forget to free output!
return output;
}

最佳答案

做了很多事情来编译它。其中一些要点只是为了摆脱警告。 :

  • 在 DES.h 的第 24 行添加\#define IP_1(x) {\
  • 在 DES_Utils.h 中,第 228 行:这里定义了 sbox_indices,并且 malloc'd 但是
    从未释放或使用过。
  • main 的正确签名应该/可以是 int main(void/* int argc, char *argv[] */),
    不使用插入的 void 作为参数。
  • 在 f = fopen() 语句周围添加 main() parent 。
    在这里你应该检查读取字节而不是!= 0。如果文件在 sizeof(unsigned long long)/CHAR_BIT 中不匹配,您将在之前读取的“tail”上工作。
  • DES_Utils.h:添加了共享函数的签名,将其余部分移至新文件 DES_Utils.c

  • 修改 DES_Utils.h:
    #ifndef GUARD_DES_Utils /* prevents errors when including twice */
    #define GUARD_DES_Utils

    //Definition of shared function !!
    unsigned long long *DES(unsigned long long, unsigned long long);
    void left_shift(int *, int, int);
    int *concatenate_arrays(int *, int *, int);
    char *bin_array_to_string(int *, int);

    int *xor_arrays(int *, char *, int);
    int *compute_sbox(int *, int);
    int *xor_int_arrays(int *, int *, int);
    void bin_array_to_hex(int *, int);

    void ull_to_bin_array(unsigned long long, int *, int);

    #endif

    6) 搬家
    #define NUM_LEFTSHIFTS 16
    int LEFTSHIFT_SCHEDULE[NUM_LEFTSHIFTS] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

    从 DES.h 到 DES.c

    7) 搬家
    #define SBOX_ROWS 4
    #define SBOX_COLS 16

    和所有 int SBOX_N 到 DES_Utils.c
    int SBOX_1[SBOX_ROWS][SBOX_COLS] =  { ...
    trough
    int SBOX_8[SBOX_ROWS][SBOX_COLS] = { ...

    8) 编译:

    对象:
    gcc -c -o obj/DES_Hash.o src/DES_Hash.c -Wall -Wextra -pedantic -std=c99 -ggdb
    gcc -c -o obj/DES_Utils.o src/DES_Utils.c -Wall -Wextra -pedantic -std=c99 -ggdb
    gcc -c -o obj/DES.o src/DES.c -Wall -Wextra -pedantic -std=c99 -ggdb

    关联:
    gcc -o ./bin/DES_Hash ./obj/DES_Hash.o ./obj/DES_Utils.o ./obj/DES.o -Wall -Wextra -pedantic -std=c99 -ggdb

    9) DES.c 中的函数 DES 不返回任何值,但无论如何都要尝试运行。
    73FB90EEDF18B09A
    SIGSEGV

    编译后的文件结构:
    .
    ├── bin
    │   └── DES_Hash
    ├── obj
    │   ├── DES_Hash.o
    │   ├── DES.o
    │   └── DES_Utils.o
    ├── src
    │   ├── DES.c
    │   ├── DES.h
    │   ├── DES_Hash.c
    │   ├── DES_Utils.c
    │   └── DES_Utils.h
    └── test
    └── input2.txt

    编辑:注意第 4 点。考虑使用类似的东西:
    #define BYTE_ULL  (sizeof(unsigned long long))

    char buffer[BYTE_ULL + 1];
    fread BYTE_ULL bytes
    buffer[BYTE_ULL] = '\0';

    并检查读取字节而不是!= 0,或者像现在一样使用但说 == 1。

    EDIT2:在 DES_Utils.c(大约第 136 行)中,bin_array_to_hex():

    这里永远不会设置 hexB 中的字节 4,因此在 map_bin_to_hex() 中调用 strtoull() 会导致处理一个未初始化的值。

    如 pt 9 和下面的评论中所述,DES() 不返回任何值,因此在尝试为 C_i 提供 Ekp_i 的值时导致 main() 中的 SIGSEGV,而 Ekp_i 永远不会从 DES() 接收指针。

    只有一个 free(),所以 valgrind 给出了一个相当填充的列表(这里有两个 free,因为我从 DES() 添加了一个 1234 的虚拟值并释放它):
    ==31352== Command: bin/DES_Hash
    ==31352==
    73FB90EEDF18B09A
    74657374696E6720
    8387236824869660448
    1234
    74657374696E63F2

    ==31352==
    ==31352== HEAP SUMMARY:
    ==31352== in use at exit: 48,417 bytes in 308 blocks
    ==31352== total heap usage: 310 allocs, 2 frees, 48,777 bytes allocated
    ==31352==
    ==31352== LEAK SUMMARY:
    ==31352== definitely lost: 47,633 bytes in 292 blocks
    ==31352== indirectly lost: 0 bytes in 0 blocks
    ==31352== possibly lost: 0 bytes in 0 blocks
    ==31352== still reachable: 784 bytes in 16 blocks
    ==31352== suppressed: 0 bytes in 0 blocks

    使用带有 --leak-check=full 的 valgrind 可以修复所有位置。

    关于C:对另一个文件中函数的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9774251/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com