我正在尝试使用UDP进行某种voip应用。我已经添加了RSA算法以确保安全。但是它给出了分段错误。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <stdlib.h>
#define LENGTH 3 /* how many seconds of speech to store */
#define RATE 8000 /* the sampling rate */
#define FILE_INPUT "/dev/dsp" /* Path to the sound card. */
#define FILE_OUTPUT "/dev/dsp"
/*-RSA-*/
//Her is gcd function
int gcd(int a,int b)
{
while(a!=b){
if(a>b)
a-=b;
else
b-=a;
}
return a;
}
//This is called Extended Euclid’s Algorithm to find d.
int findD(int e,int n)
{
int f=e;
int d=n;
int x1, x2, x3, y1, y2, y3;
x1 = 1; x2 = 0; x3 = f; //p
y1 = 0; y2 = 1; y3 = d; //d
int q = 0, i = 1;
int t1 = 0, t2 = 0, t3 = 0;
do
{
if (i == 1)
{
q = x3 / y3;
t1 = x1 - (q * y1);
t2 = x2 - (q * y2);
t3 = x3 - (q * y3);
}
else
{
x1 = y1; x2 = y2; x3 = y3;
y1 = t1; y2 = t2; y3 = t3;
q = x3 / y3;
t1 = x1 - (q * y1);
t2 = x2 - (q * y2);
t3 = x3 - (q * y3);
}
i++;
if (y3 == 0)
{
break;
}
} while (y3 != 1);
if (y3 == 0)
{
//printf("Sayinin tersi yoktur!!!!");
}
else
{
// printf("\nSayinin tersi : %d" , y2);
}
if(y2<=0)
{
y2=e+y2;
}
return y2;
}
//Instead of using pow function,I have choose to write square and multiply method which is faster and
//more suitable for big integers.Because we have no such a change to find 104^30 such like that
//Here computes pow(a,b)%n
int squareMul(int a,int b,int n)
{
int y = 1;
/* Compute pow(a, b) % n using the binary square and multiply method. */
while (b != 0)
{
/* For each 1 in b, accumulate y. */
if (b & 1)
{
y = (y * a) % n;
}
/* Square a for each bit in b. */
a = (a * a) % n;
/* Prepare for the next bit in b. */
b = b >> 1;
}
return y;
}
//Encyrption function
//Assume our plain-text is M
int *encyrpt(int text[],int e,int n)
{
int t=0;
int *s=(int *)malloc(100);
for(t=0;t<sizeof(text);t++)
{
int gec=(int)text[t];
//Here computes E(M)=M^e mod n;
s[t]=squareMul(gec,e,n);
}
return s;
}
//Here is decyrption
//Assume our chipher-text is C
int *decyrpt(int enc[],int d,int e,int n)
{
int i=0;
int *s=(int *)malloc(100);
for(i=0;i<sizeof(enc);i++)
{
int gelenEnc=(int)enc[i];
//Here computes D(C)=C^d mod n;
s[i]=squareMul(gelenEnc,d,n);
}
return s;
}
//Here is totient function to find prime to m.
int totient(int m)
{
int i;
int ph=1;
for(i=2;i<m;i++){
if(gcd(i,m)==1)
{
ph=i;
break;
}
}
return ph;
}
/*-RSA-*/
int main()
{
int sock,bytes_recv;
struct sockaddr_in server_addr;
struct hostent *host;
char send_data[LENGTH*RATE];
char recv_data[LENGTH*RATE];
int addr_len, bytes_read;
struct client_addr;
/* this buffer holds the digitized audio */
unsigned char buf[LENGTH*RATE];
/*----------RSA-----------------------*/
//Here are some variables that I used for RSA ALGORİTHM
//str is our plain-text
char *plainText;
int *ascii;
int *enc;
int *dec;
int p,q;
int k=0;
int n;
int e;
int c;
int phi;
int d;
plainText="Merhaba";
//Here enter 2 relatively prime number
//I have chose the p=73 and q=151
p=73;
q=151;
printf("\n\ p :%d and q :%d \t \n",p,q);
//Here computes n
n = p*q;
//Here computes phi func simply
phi=(p-1)*(q-1);
printf("\n\ n :\t= %d \n",n);
printf("\n\ Phi :\t= %d \n",phi);
//Here Euilers Totient function.It finds a number 'e' which is relatively prime with phi.
e=totient(phi);
//Here computes d,which is multiplicative inverse of e modula phi.
d=findD(phi,e);
printf("\n\ e :\t= %d \n",e);
printf("\n\ d :\t= %d which is multiplicative inverse of e modula phi \n",d);
//Here is the ascii values for plainText.I have created new array in order to store plainText's ascii for simplicty
ascii=(int *)malloc(sizeof(int)*sizeof(plainText)/sizeof(char));
/*---------------RSA------------*/
int sound_device;
/* open sound device */
//I defined sound card both read and write mode for simplicity
sound_device = open("/dev/dsp", O_RDWR);
if (sound_device < 0) {
perror("Open sound card failed");
exit(1);
}
host= (struct hostent *) gethostbyname((char *)"127.0.0.1");
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
while(1){
read(sound_device, buf, sizeof(buf)); /* record some sound */
printf("\n Size of buff: %d",sizeof(buf));
ascii=malloc(LENGTH*RATE);
buf=malloc(LENGTH*RATE);
printf("\n Size of ascii: %d",sizeof(ascii));
//Here ascii stores plaintText's ascii number.
for(c=0;c<LENGTH*RATE;c++)
{
int k=(int)buf[c];
ascii[c]=k;
printf("\n\t Ascii's of %c \t= %d \n",buf[c],ascii[c]);
printf("\n\t C: %c \t= %d \n",c);
}
enc=encyrpt(ascii,e,n);
//Send function to server
sendto(sock, enc, LENGTH*RATE, 0,(struct sockaddr *)&server_addr, sizeof(struct sockaddr));
//Listen from server for 3 seconds
ioctl(sound_device, SOUND_PCM_SYNC, 0);
bytes_recv = recvfrom(sock,buf,LENGTH*RATE,0,(struct sockaddr *)&server_addr, &addr_len);
printf("\n Sended:");
if(bytes_recv==LENGTH*RATE){
printf("\nMessage received from server,listen:");
//Here is decyription
dec=decyrpt(buf,d,e,n);
write(sound_device, dec, sizeof(dec));
ioctl(sound_device, SOUND_PCM_SYNC, 0);
}
}
}
Ascii's of � = 131
C: � = 10989
分段错误
然而,我的RSA算法在其他char数组中正常运行。任何想法? 感谢
答案 0 :(得分:2)
正如评论中的人们指出的那样,你应该使用调试器来找出确切发生分段错误的位置。
然而,粗略分析(开发人员在挖掘调试器之前应该总是这样做)显示了许多正在使用的指针。
每次拨打malloc
时,都应该确认它是成功的。如果不是,并且您尝试使用malloc
编辑的指针,则可以获得段错误。
您还可以为非malloc
指针指定一个字符串(plainText
)... BOOM:segfaults,啊!
您的一系列功能也会取消选中malloc
。
所以,你应该看一些地方。
答案 1 :(得分:2)
分段错误通常是由于尝试访问未为进程分配的内存而引起的。当您索引到数组(特别是动态创建的数组)时,通常会出现这种情况。
在您的代码中,您在malloc()
和encypt()
函数中拥有固定大小的decrypt()
,但您可以根据输入数组的大小访问其元素,可能成为seg.fault的原因。
可以肯定的是,您需要使用调试器并查看上/下索引发生的位置。一定要检查访问其他数组(无论是否动态分配)
此外,sizeof(plainText)
返回指向字符的指针的大小,而不是字符串的长度。您需要将plaintext
声明为基于堆栈的数组,或使用strlen()
函数。