2012-06-06 55 views
-1

我試圖做一些使用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算法正常工作在其他字符數組separetly.Any想法? 謝謝

+4

你有沒有聽說過調試器? – 2012-06-06 15:12:24

+4

您應該使用調試器來確定導致seg故障的線路,然後從那裏向後工作。 –

+0

你的代碼用'gcc -Wall ...'產生16個警告 - 其中一些可能很重要 - 你應該修復所有這些警告。 –

回答

2

分段錯誤通常是由嘗試訪問未分配給進程的內存引起的。這通常是在您將數組編入索引時(特別是動態創建的)。

在你的代碼必須在encypt()decrypt()功能的固定大小的malloc(),但您可以根據輸入陣列,這可能是爲seg.fault原因的大小訪問它的元素。

可以肯定的是,您將需要使用調試器並查看發生過度/不足索引的位置。一定要檢查訪問其他陣列以及(無論是否動態分配)

而且,sizeof(plainText)返回指向字符的指針的大小,而不是字符串的長度。您將需要將plaintext聲明爲基於堆棧的陣列,或使用strlen()函數。

2

正如評論中的人們指出的那樣,您應該使用調試器來確定分段故障發生的位置。

但是,粗略的分析(這是開發者在挖掘調試器之前應該始終做的事情),它顯示了許多指針,這些指針正被毫無保留地使用。

任何時候你打電話給malloc,你都應該確認它是成功的。如果不是,並且您嘗試使用malloc編輯的指針,則可以獲得段錯誤。

您還將一個字符串分配給一個un malloc ed指針(plainText)... BOOM:segfaults,ahoy!

你的一些函數也可以不選中malloc s。

所以,有幾個地方你應該看看。

+0

謝謝答案。我會試着找出這個問題 – user1440102