C언어의 해싱 코드 구성

안녕하세요 

프로젝트를 하고 있는데요

c언어로 해싱 및 복호화 과정을 코드로 간단히 작성하고 발표를 할건데요

우리가 3가지 방법을 선택했습니다 

1. 제산함수 

2. 중간제곱함수 

3. 폴딩함수


완성을 못하고 있습니다 

도와주실 수 있을까요


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAX_CODE_LENGTH 50


// 암호화된 코드를 저장하는 배열

char encryptedArray[5][MAX_CODE_LENGTH];


//제산 해시함수 

/* 문자열 -> 문자의 아스키코드를 모두 더한 값,

    숫자 -> 각 숫자를 모두 더한 값을 해시값으로 선정) */

int additiveHash(char* code) {

    int hash = 0;

    for (int i = 0; i < strlen(code); i++) {

        hash += code[i];

    }

    return hash;

}


//폴딩 해시함수

/* 코드의 길이를 자릿수만큼 나누어,

     다시 합산한 후 반환하는 함수*/

int foldingHash(char* code) { 

    int hash = 0;

    int len = strlen(code);

    int step = len / 4; // 나눠서 합치는 간격


    for (int i = 0; i < len; i += step) {

        int segment = 0;

        for (int j = 0; j < step && (i + j) < len; j++) {

            segment = segment * 10 + code[i + j];

        }

        hash += segment;

    }


    return hash;

}


//중간제곱 함수

//제곱한 값을 해쉬값으로 반환

int squareHash(int number) {

    return number * number;

}


// 구조체 정의

typedef struct {

    char codes[5][5]; // 최대 5개의 암호화된 코드 저장

    int count; // 현재 저장된 코드의 개수

} EncryptedCodes; // EncryptedCodes라는 구조체로 정의


// 사전 코드 입력 함수

// advancedCode는 4자리 까지만 지정하기 위한 배열 5 선언

void enterAdvancedCodes(char advancedCode[][5], int numCodes) { //numCodes는 메인에 5로 지정되어있음.

    printf("사전 코드를 입력하세요:\n");

    for (int i = 0; i < numCodes; i++) { // 최대 5개의 사전코드 지정

        printf("%d번째 사전코드: ", i + 1);

        scanf("%s", advancedCode[i]); // advancedCode[i] 배열에 저장

    }

}


// 메뉴 함수 정의

int showMenu() {

    int choice;

    printf("\n------ 메뉴 ------\n");

    printf("0. 사전코드 목록 출력\n");

    printf("1. 암호화\n");

    printf("2. 암호화된 목록 출력\n");

    printf("3. 모두 복호화 및 배열 초기화\n");

    printf("4. 종료\n");

    printf("메뉴를 선택하세요: ");

    scanf("%d", &choice);

    return choice;

}


// 암호화 함수 정의

void encrypt(EncryptedCodes* encryptedCodes, char advancedCode[][5], int numCodes) {

    char inputCode[5]; // 최대 4글자까지만 수용, 넘은경우 4글자까지만 잘라서 수용함

    int hashChoice;

    int hashValue;


    printf("암호화할 코드를 입력하세요 (4글자): ");

    scanf("%s", inputCode);


    // 코드 일치 여부 확인

    int match = 0;

    for (int i = 0; i < numCodes; i++) { // numCodes는 메인에서 5로 초기화 되어있음

        if (strcmp(inputCode, advancedCode[i]) == 0) { //strcmp : 문자열이 완전히 같다면 0 반환

            match = 1;

            break;

        }

    }


    if (!match) {

        printf("코드가 일치하지 않습니다.\n");

        return;

    }


    printf("해싱 처리할 함수를 선택하세요 (1. 제산함수, 2. 폴딩함수, 3. 중간제곱 함수): ");

    scanf("%d", &hashChoice);

    // 해싱 처리

    if (hashChoice == 1) { // 제산함수

        hashValue = additiveHash(inputCode);

    } else if (hashChoice == 2) { // 폴딩함수

        hashValue = foldingHash(inputCode);

    } else if (hashChoice == 3) { // 중간제곱 함수

        // 숫자인 경우만 중간제곱 함수 사용

        if (inputCode[0] >= '0' && inputCode[0] <= '9') {

            int number = atoi(inputCode); //코드를 정수로 변환

            hashValue = squareHash(number); //수를 제곱하여 해쉬 값으로 지정

        } else {

            printf("타입이 문자인 경우, 중간제곱 함수를 사용할 수 없습니다.\n");

            return;

        }

    } else {

        printf("올바른 번호를 선택하세요.\n");

        return;

    }


    // 충돌 처리

    if (hashValue % 2 == 0) {

        // 암호화 할 코드가 짝수인 경우 선형 조사법 - 충돌 발생 시 배열에서 다음 빈 슬롯을 찾아 해시 값을 조정함

        int i = 1; // 선형 조사법에 사용될 간격을 나타내는 변수

        while (encryptedCodes->codes[i % 5][0] != '\0') { // i%5의 위치가 비어 있는지 확인

            hashValue += i; // 비어있지 않다면? -> 충돌 발생, hashvalue에 i를 더하여 다음 위치 계산, 새로운 해시 값 얻을 수 있음

            i++;

        }

    } else {

            // 홀수인 경우 체이닝

            int index = hashValue % 5; // hashValue를 배열의 크기로 나눈 나머지를 취해 배열 내 위치 저장 결정

            while (encryptedCodes->codes[index][0] != '\0') { // 선택한 인덱스에 다른 코드가 존재하는지 확인

                index = (index + 1) % 5; // 충돌이 발생하면 다음 슬롯으로 이동하여 빈 슬롯을 찾기위해 인덱스를 증가시킴

            }

            hashValue = index;

        }


    sprintf(encryptedArray[hashValue % 5], "%d", hashValue); // 해싱된 값을 암호화 한 배열에 저장

    strcpy(encryptedCodes->codes[hashValue % 5], inputCode); // 암호화 이전 코드를 복호화 목록에 저장

    printf("암호화 완료! 해싱된 코드: %d\n", hashValue);

}


// 사전 코드 출력 함수

void printAdvancedCodes(char advancedCode[][5], int numCodes) {

    printf("\n--- 사전 코드 목록 ---\n");

    for (int i = 0; i < numCodes; i++) {

        if (advancedCode[i] != 0) {

            printf("%d번 사전코드: %s\n", i + 1, advancedCode[i]);

        }

    }

    printf("------------------------\n");

}


// 암호화된 배열 출력 함수

void printEncryptedArray() {

    printf("\n--- 암호화된 코드 목록 ---\n");

    for (int i = 0; i < 5; i++) {

        if (encryptedArray[i][0] != '\0') {

            printf("암호화된 %d번 사전코드: %s\n", i + 1, encryptedArray[i]);

        }

    }

    printf("------------------------\n");

}


// 복호화 함수 출력

void decrypt(EncryptedCodes* encryptedCodes) {

    printf("\n--- 복호화된 코드 목록 ---\n");

    for (int i = 0; i < 5; i++) {

        if (encryptedArray[i][0] != '\0') { //저장된 공간 중 빈 배열이 아닌 것을 복호화함.

            printf("복호화된 코드 %d번: %s\n", i + 1, encryptedCodes->codes[i]); //원래의 사전 코드 번호와, 사전 코드가 나옴

        }

    }

    printf("------------------------\n");


    // 배열 초기화

    for (int i = 0; i < 5; i++) {

        encryptedCodes->codes[i][0] = '\0';

    }


    encryptedCodes->count = 0;

    printf("복호화 완료! 배열 초기화됨.\n");

}


int main() {

    char advancedCode[5][5]; // 최대 5개의 코드를 저장할 배열

    int numCodes = 5; // 저장할 코드의 개수

    enterAdvancedCodes(advancedCode, numCodes);

    EncryptedCodes encryptedCodes;

    encryptedCodes.count = 0;


    while (1) {

        int choice = showMenu();


        switch (choice) {

            case 0: //사전코드 출력

                printAdvancedCodes(advancedCode, numCodes);

                break;

            case 1: // 암호화 하기

                encrypt(&encryptedCodes, advancedCode, numCodes);

                break;

            case 2: // 암호화 된거 출력

                printEncryptedArray();

                break;

            case 3: // 복호화 된거 출력 후 초기화

                decrypt(&encryptedCodes);

                break;

            case 4: // 종료

                printf("프로그램을 종료합니다.\n");

                return 0;

            default:

                printf("올바른 메뉴 번호를 선택하세요.\n");

        }

    }


    return 0;

}


다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2023년 11월 17일 오후 12:22

조회 82

댓글 0

    함께 읽은 게시물

    🤔 API 키와 토큰의 차이

    ... 더 보기

    API keys vs tokens - what's the difference?

    Medium

    API keys vs tokens - what's the difference?

     • 

    저장 313 • 조회 9,884


    리더. 국어사전을 보면 조직이나 단체에서 전체를 이끌어가는 위치에 있는 사람이라고 기술되어 있다. 지식백과사전에는 어떤 조직이나 단체에서 목표의 달성이나 방향에 따라 이끌어 가는 중심적인 위치에 있는 사람, 구성원들에 대한 결정의 책임을 지고 또한 집단 외부와의 조정 기능의 역할도 하는 사람이라고 되어 있다.

    ... 더 보기

    [시사뉴스] 【박성태 칼럼】 리더가 독재를 하게 되는 두가지 이유

    www.sisa-news.com

    [시사뉴스] 【박성태 칼럼】 리더가 독재를 하게 되는 두가지 이유

    스몰 데이터(Pandas)에서 빅 데이터(Spark)로!

    ... 더 보기

     • 

    댓글 1 • 저장 29 • 조회 3,713


    React 면접 전 살펴보기 위한 Q&A 40가지 (2024년 ver)

    1. R

    ... 더 보기

    Top 40 ReactJS Interview Questions and Answers in 2024 | Simplilearn

    Simplilearn.com

    Top 40 ReactJS Interview Questions and Answers in 2024 | Simplilearn

     • 

    댓글 1 • 저장 218 • 조회 11,578


    📢 실무 프로젝트로 성장하고 싶은 주니어 개발자 분들에게

    ... 더 보기

    패스트캠퍼스 : INNER CIRCLE | 패스트캠퍼스

    bit.ly

    패스트캠퍼스 : INNER CIRCLE | 패스트캠퍼스

     • 

    저장 73 • 조회 5,790


    주니어 개발자들이 읽으면 좋은 테크 아티클 모음📚

    F-Lab 에서 주니어 개발자들이(사실 개발자라면 누구나) 보시면 좋을 아티클 모음을 공유해 주었네요! 검색엔진부터 비동기 처리, NoSQL 등 다양한 분야의 아티클들이 공유되어 있으니 관심있으신 분들은 보시면 좋겠습니다. F-Lab 에서 공유해주신 아티클 주제를 나열해보면 다음과 같습니다. 📌 구글이 직접 말하는 검색엔진의 원리 (tali.kr) 📌 검색 엔진은 어떻게 작동하는가 (xo.dev) 📌 네이버의 검색엔진의 특징과 알고리즘 (tistory.com) 📌 [네이버 블로그]네이버 검색의 원리 : 네이버 블... 더 보기

    주니어 개발자들이 읽으면 좋은 테크 아티클 모음

    F-Lab : 상위 1% 개발자들의 멘토링

    주니어 개발자들이 읽으면 좋은 테크 아티클 모음

     • 

    저장 142 • 조회 3,846