我正在尝试调用另一个文件中定义的C函数。我将函数的定义添加到头文件中并将其包含在两个.c文件中,但我仍然收到错误:
C:\ Users \ Hunter \ AppData \ Local \ Temp \ ccyqsulH.o:
在函数
中main': C:DES_hash.c:42: undefined reference to
DES'collect2:ld返回1 退出状态
这是函数原型定义:
/* 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;
}
答案 0 :(得分:1)
在 GUARD_DES_Utils之前包含。
/* DES_Utils.h */
#include "DES.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef GUARD_DES_Utils /* prevents errors when including twice */
...
移动包含到包含的主体。防护装置。
答案 1 :(得分:1)
如果您尝试仅编译DES_hash.c
,链接器将抱怨</ p>
In function main': C:DES_hash.c:42: undefined reference to DES'
这是自然的,因为在DES()
中定义了DES.c
,并且您没有在链接过程中包含它。现在,你必须做的就是编译gcc DES.c DES_hash.c
;但是你做了一个boo-boo:你已经在头文件(DES_Utils.h
)中定义了函数。这意味着,只要某些内容包含DES_Utils.h
,就会定义这些函数,这很糟糕。在这种特殊情况下,某些函数在DES_hash.c
和DES.c
中定义,并且链接器很混乱,不知道要链接哪个函数。
解决问题的最简单方法是将函数定义从DES_Utils.h
移动到新文件DES_Utils.c
,只在标题中保留公共接口的声明。另外,如果多个DES.h
文件中需要或在单个static
文件中定义,请确保您在.c
中定义的数组.c
为标头。
答案 2 :(得分:1)
有很多东西需要编译。其中一些要点只是为了摆脱警告。 :
将\添加到DES.h第24行#define IP_1(x){\
在DES_Utils.h中,第228行:这里定义了sbox_indices,并且malloc'd但是 从来没有释放过NOR。
主要的正确签名应该/可能是int main(void / * int argc,char * argv [] * /), 不使用插入的void作为参数。
在f = fopen()语句周围添加main()parenteses
在这里你应该检查读取字节而不是!= 0. 如果文件在sizeof(unsigned long long)/ CHAR_BIT中不匹配,你将从之前的读取开始“尾巴”。< / strike>
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(aprox第136行)中,bin_array_to_hex():
这里从未设置hexB中的字节4,因此在map_bin_to_hex()中调用strtoull()会导致处理单位化值。
正如第9页及下面的评论所述,DES()不会返回任何值,因此在尝试向C_i提供Ekp_i的值时会在main()中产生SIGSEGV,而Ekp_i的值永远不会从DES()接收指针。
只有一个 free(),所以valgrind给出了一个相当充满的列表(这里是两个自由,因为我从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
使用valgrind和--leak-check = full可以修复所有位置。
答案 3 :(得分:0)
我在Linux和GCC工作,但我希望它会有所帮助:
对我来说,看起来你没有静态链接它,因此主代码需要在运行时加载库。如果可能的话,静态链接它,或者使用的库可以显示在您的代码中(在Linux中你可以在W中设置LD_LIBRARY_PATH
,我不知道)