自己用CUDA做的簡單的加密程式

洛欣發表於2009-11-13

這是偶們C++教材練習3中的加密解密題,現在移植到CUDA計算平臺上面.
由於計算的數值比較小,而且出現多次記憶體host與視訊記憶體device之間的資料複製,
因此這個CUDA程式會比CPU運算的慢不少.
                                      楊漱玉青Ruby

謝謝諸位來捧場啦...

[code]#include
#include
#include
#include

//#define THREAD_NUM 100
//#define BLOCK_NUM 1

__shared__ int num[7]/*={4,9,6,2,8,7,3}*/;  /*申請位於共享儲存器中的空間,
                                                 考慮到這是固定的數值,
                                                 或許可以申請放到紋理儲存器或者固定儲存器中. */


bool InitCUDA()   //CUDA裝置初始化
{
    int count;

    cudaGetDeviceCount(&count);
    if(count == 0)
    {
        fprintf(stderr, "There is no device.\n");
        return false;
    }

    int i;
    for(i = 0; i < count; i++)
    {
        cudaDeviceProp prop;
        if(cudaGetDeviceProperties(&prop, i) == cudaSuccess)
        {
            
            if(prop.major >= 1)
            {
                break;
            }

        }
    }

    if(i == count)
    {
        fprintf(stderr, "There is no device supporting CUDA 1.x.\n");
        return false;
    }

    cudaSetDevice(i);

    cudaDeviceProp prop;

    cudaGetDeviceProperties(&prop, i);

    printf("顯示卡GPU型號為:");
    printf("%s",prop.name);
    printf("\n");
    printf("支援的CUDA計算能力的版本為:");
    printf("%d",prop.major);
    printf(".%d",prop.minor);
    printf("\n");



    return true;
}

__global__ static void encryption(char *between,char *finall/*,int *cudatag*/)   //加密函式
{
    const int tid=threadIdx.x;
    //int num[7]={4,9,6,2,8,7,3};
    num[0]=4;num[1]=9;num[2]=6;num[3]=2;num[4]=8;num[5]=7;num[6]=3;
    between[tid]+=num[tid%7];

    if((between[tid]>=32)&&(between[tid]<=122))
        {
            finall[tid]=between[tid];
        }
    else
        {

            finall[tid]=(between[tid]-122)+32;
            //finall[tid]=((between[tid]%90)+32); //加密操作.
        }

    __syncthreads();

    //finall[tid]=(between[tid]-122)+32;
}
   



int main()
{

    if(!InitCUDA())
    {
        return 0;
    }

    printf("CUDA initialized.\n");

    char original[100];
    char *between;
    char *finall;

    int tag=0;
    //int *cudatag;
    int i;

    printf("請輸入你想要加密的文字:");

    for(i=0;i<100;i++)  //原文
    {
        original[i]=getchar();
        if(original[i]=='\n')
        {
            tag=i;
            break;
        }
    }

    char hostfinall[100];  //儲存加密後的值

    clock_t time2;
    clock_t time1=clock();

    cudaMalloc((void**) &between,sizeof(int)*tag);  //申請視訊記憶體空間
    cudaMalloc((void**) &finall,sizeof(int)*tag);
    //cudaMalloc((void**) &cudatag,sizeof(int));  //標識陣列大小變數

    //cudaMallocArray( struct cudaArray** array,const struct cudaChannelFormatDesc* desc,size_t width,size_t height )

    cudaMemcpy(between, original, sizeof(char)*tag, cudaMemcpyHostToDevice);  //陣列複製
    //cudaMemcpy(cudatag,&tag,sizeof(int),cudaMemcpyHostToDevice);

    encryption<<<1,tag,7>>>(between,finall/*,cudatag*/);  //執行device部分

    cudaMemcpy(hostfinall,finall,sizeof(char)*tag,cudaMemcpyDeviceToHost);  //結果複製

    cudaFree(between);   //釋放視訊記憶體
    cudaFree(finall);
    //cudaFree(cudatag);
    time2=clock()-time1;

    printf("加密之後的文字為:");

    for(i=0;i<=tag;i++)
        printf("%c",hostfinall[i]);

    printf("\n");
    printf("GPU加密消耗的時間為:%d",time2);

    printf("\n");

    system("pause");
}[/code]


額,CPU版本的在這裡:

[code]#include
#include
#include

using namespace std;

/*練習三加密解密作業,基於Visual Stdio 2008構建,希望我還能做出基於CUDA運算的版本.

                                                    楊漱玉青Ruby */

int main()
{
    char original[100];  //原文
    char between[100];  //中間.
    char finall[100]; //最終加密結果

    int module[100];  //解密時需要標記是否被模運算過

    int quotient[100]; /*記錄其中模運算中的商值,為解密做準備,
                        這樣的解密思想貌似不正確,或許可以窮舉商,
                        來和原文逐一比較,不過這樣會增加運算量,
                        但是卻更貼近實際.*/

    int i,j;  //迴圈變數
    int tag; //標記輸入了多少字元變數

    for(i=0;i<100;i++)   //初始化module陣列
    {
        module[i]=0;
    }

    cout<
    for(i=0;i<100;i++)
    {
        original[i]=getchar();
        if(original[i]=='\n')
        {
            tag=i-1;
            break;
        }
    }

    char num[7]={4,9,6,2,8,7,3};  //加數

    j=0;

    clock_t time2;
    clock_t time1=clock();
    //加密操作

    for(i=0;i<=tag;i++)
    {
        between[i]=original[i]+num[j];  //加法操作

        j++;

        if(j==7)
            j=0;
    }

    for(i=0;i<=tag;i++)
    {
        if((between[i]>=32)&&(between[i]<=122))
        {
            finall[i]=between[i];
            module[i]=1;   //標記該數未被模運算過
        }
        else
        {
            quotient[i]=between[i]/90;  //儲存商,做解密準備,此處有爭議,或許是題目理解不正確.

            finall[i]=(between[i]-122)+32;
            //finall[i]=((between[i]%90)+32); //加密操作.
        }
    }
    //cout<
    time2=clock()-time1;

    cout<
    for(i=0;i<=tag;i++)
        cout<    cout<
    cout<
    //解密操作

    j=0;

    for(i=0;i<=tag;i++)   
    {
        if(module[i]==1)
        {
            between[i]=finall[i];
        }

        else if(module[i]==0)
        {
            //between[i]=((finall[i]-32)+quotient[i]*90);
            between[i]=(finall[i]-32)+122;
        }

        between[i]-=num[j];
        j++;

        if(j==7)
            j=0;

    }

    int tag2=0;

    for(i=0;i<=tag;i++)
    {
        if(original[i]!=between[i])
            tag2=1;
    }

    if(tag2)
    {
        cout<    else
    {
        cout<
        for(i=0;i<=tag;i++)
            cout<        cout<    }

    system("pause");

    return 0;
}[/code]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22785983/viewspace-619575/,如需轉載,請註明出處,否則將追究法律責任。

相關文章