C++에서 조회 테이블 만들기

Jay Shaw 2023년10월12일
  1. C++에서 조회 테이블 만들기
  2. C++에서 32비트 값에 대한 순환 중복성을 표시하는 조회 테이블 만들기
  3. C++에서 미리 초기화된 조회 테이블 만들기
  4. C++에서 주어진 인덱스 내에서 가능한 모든 값을 찾기 위한 조회 테이블 만들기
  5. 결론
C++에서 조회 테이블 만들기

임베디드 시스템은 합리적인 가격으로 공급업체에 제공되는 저렴한 CPU로 만들어진 단순한 하드웨어 장치입니다. 이러한 가격 인하에는 제한된 처리 능력이 필요하며 종종 이러한 장치는 스택 오버플로의 위험이 있습니다.

이러한 위험을 피하기 위해 조회 테이블을 사용할 수 있습니다. 조회 테이블은 무언가에 대한 데이터를 저장하는 배열로, 실시간으로 수행되는 경우 많은 처리 능력을 필요로 합니다.

룩업 테이블은 이러한 문제에 대한 비용 효율적인 솔루션을 제공합니다.

이 기사에서는 룩업 테이블의 개념, 구현, 단점 및 이해를 돕기 위한 몇 가지 코드 블록에 대해 설명합니다.

C++에서 조회 테이블 만들기

이 문서에서 조회 테이블은 세 가지 다른 방식으로 생성됩니다.

  1. 프로그램이 자체적으로 생성하는 룩업 테이블.
  2. 수동 룩업 테이블은 프로그램 시작 시 초기화되며 나중에 참조용으로 사용됩니다.
  3. 주어진 인덱스 내에서 가능한 모든 값을 찾기 위해 변수 세트로 생성된 조회 테이블을 선언하는 프로그램.

위에서 언급한 세 가지 경우는 조회 테이블이 실제 시나리오에서 사용되는 가능한 모든 방법입니다.

C++에서 32비트 값에 대한 순환 중복성을 표시하는 조회 테이블 만들기

이 예에서는 32비트 CRC 계산에 대한 순환 중복성을 확인하는 조회 테이블을 만듭니다. 일부 규칙에서는 CRC를 PEC라고도 하지만 둘 다 같은 의미입니다.

다음 코드 블록은 256비트 데이터에 대한 CRC 계산 테이블을 인쇄하는 조회 테이블을 만듭니다.

패키지 가져오기

프로그램은 다음과 같은 두 가지 가져오기 패키지를 사용합니다.

  1. iostream - 입출력 작업용
  2. iomanip - 프로그램의 최종 결과를 변경합니다.

C++에서 조회 테이블을 만드는 메서드 함수

첫 번째 방법인 make_pec_tabletable_pec 배열을 매개변수로 사용합니다. 이 방법은 8비트 데이터를 처리하고 32비트로 확장됩니다.

do-while 루프는 rem과 1 사이의 더 큰 값을 확인하고 이를 value_of_polynomial 변수의 거듭제곱으로 올립니다. do-while 루프는 x 값이 0이 아닌 상태로 유지될 때까지 실행됩니다.

pec_gen 메소드는 pec 테이블을 저장하는 부호 없는 변수 pec를 생성합니다. 여기서 table_pec 배열 내부의 값은 for 루프를 사용하여 여기에 삽입됩니다.

메인 함수 내에서 로컬 배열 table_pec은 다시 256비트 크기로 생성됩니다. 그런 다음 make_pec_table 메소드가 호출되고 table_pec 배열이 매개변수로 전달됩니다.

마지막으로 모든 256비트 데이터에 대한 결과가 인쇄됩니다.

#include <iomanip>
#include <iostream>

void make_pec_table(unsigned long table_pec[]) {
  unsigned long value_of_polynomial = 0xEDB8320;
  unsigned long rem;
  unsigned char x = 0;
  do {
    // proceed  with data byte
    rem = x;
    for (unsigned long bit = 8; bit > 0; --bit) {
      if (rem & 1)
        rem = (rem >> 1) ^ value_of_polynomial;
      else
        rem = (rem >> 1);
    }
    table_pec[(size_t)x] = rem;
  } while (0 != ++x);
}

unsigned long pec_gen(unsigned char *m, size_t n, unsigned long table_pec[]) {
  unsigned long pec = 0xfffffffful;
  size_t i;
  for (i = 0; i < n; i++) pec = table_pec[*m++ ^ (pec & 0xff)] ^ (pec >> 8);
  return (~pec);
}

int main() {
  unsigned long table_pec[256];
  make_pec_table(table_pec);
  // display PEC table
  for (size_t i = 0; i < 256; i++) {
    std::cout << std::setfill('0') << std::setw(8) << std::hex << table_pec[i];
    if (i % 4 == 3)
      std::cout << std::endl;
    else
      std::cout << ", ";
  }
  return 0;
}

C++에서 미리 초기화된 조회 테이블 만들기

다음 예는 SHA256 암호화 알고리즘의 코드 블록입니다. 프로그램은 두 세트의 레지스터를 생성합니다(프로그램이 참조할 수 있도록 수동으로 생성한 조회 테이블에 불과함).

첫 번째 레지스터 세트는 처음 64자리 숫자의 16진수 값을 해시 키로 저장하는 데 사용되는 레지스터입니다. 이 키의 값은 hash_functions 생성자 클래스에 있는 hash_keys 변수에 저장됩니다.

const unsigned int hash_functions::hash_keys[64] = {
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
    0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
    0x243185be, 0x550c7dc3, .....}

기본적으로 데이터 읽기는 조회 테이블의 유일한 목적입니다. 룩업 테이블을 변경할 수 있는 경우 이는 실수를 나타냅니다.

이러한 시나리오를 피하기 위해 어레이는 처음에 const로 선언됩니다.

배열에는 처음 64개의 자연수의 16진수 값이 포함되어 있으므로 부호에 대한 추가 비트가 필요하지 않습니다. 따라서 배열은 unsigned로 선언됩니다.

조회 테이블에 음수 값이 있는 경우 배열은 서명된 데이터 유형으로 선언되어야 합니다.

초기화된 다른 상태 레지스터 세트는 처음 8개 정수에 대해 유사한 16진수 값 세트를 저장합니다.

void hash_functions::stateregister() {
  s_r[0] = 0x6a09e667;
  s_r[1] = 0xbb67ae85;
  s_r[2] = 0x3c6ef372;
  .....
}

이 두 조회 테이블은 시간 복잡성을 줄이고 처리 속도를 높이기 위해 프로그램에 미리 초기화됩니다.

SHA256 변환 자체가 CPU의 긴 프로세스이기 때문입니다. 런타임 중에 이러한 값을 계산하도록 프로그래밍된 경우 프로그램의 시간 복잡성이 크게 증가합니다.

룩업 테이블이 초기화되면 다른 변수처럼 호출하여 사용할 수 있습니다.

조회 테이블을 다른 메소드 내부가 아닌 별도의 생성자 내부에 추가하는 이유는 조회 테이블이 거대한 디스크 공간을 차지하기 때문입니다. 따라서 전역 범위 또는 정적 엔터티로 선언해야 합니다.

조회 테이블이 메소드 내부에서 로컬 엔티티로 초기화된다고 가정합니다. 이 경우 메서드가 호출될 때마다 초기화 프로세스가 반복됩니다.

프로그램 실행 중간에 초기화가 큰 메소드를 삽입하는 것은 좋지 않습니다.

시작 또는 전역 범위에서 조회 테이블을 갖는 것은 유리하고 비용 효율적입니다.

for (int n = 0; n < 64; n++) {
  t1 = buffer[7] + hash_keys[n] + w[n];
}
for (n = 0; n < 8; n++) {
  s_r[n] += buffer[n];
}

여기서 애플리케이션은 초기화 단계에서 이러한 값을 읽을 때 많은 시간과 처리 능력을 소모한다는 점에 유의해야 합니다. 초기화가 발생하면 프로그램은 값 사이를 확인하기 위해 최소한의 처리 능력이 필요합니다.

이전 세대의 컴퓨터 시스템과 전자 장치는 메모리와 디스크 공간이 매우 적었기 때문에 여전히 우려의 대상입니다. 결과적으로 이러한 장치의 펌웨어에서 조회 테이블을 사용하면 많은 디스크 공간을 차지할 수 있습니다.

조회 테이블을 보유하는 변수는 위의 예에서 const 또는 상수 변수로 지정되었습니다. 컴파일러가 조회 테이블에 아무것도 쓰지 않도록 지시하기 위해 수행되었습니다.

const가 정의되어 있어도 응용 프로그램은 종종 조회 테이블을 RAM으로 강제 실행합니다. 매우 귀중한 리소스이기 때문에 프로그래머는 변수를 선언하면서 flash라는 용어를 하드코딩해야 합니다.

‘플래시’는 애플리케이션 속도에 병목 현상을 일으키는 느린 형태의 메모리이지만 소중한 RAM을 절약합니다.

C++에서 주어진 인덱스 내에서 가능한 모든 값을 찾기 위한 조회 테이블 만들기

이 특정 예는 주어진 포인트와 차수에 대한 사인파 함수의 값을 표시합니다.

패키지 가져오기

이 예에는 세 가지 가져오기 패키지가 필요합니다.

  1. iostream.h
  2. math.h
  3. conio.h

iostream 패키지에는 입출력 작업에 대한 의미가 있습니다. math.h 패키지는 수학 함수 및 삼각 함수를 호출하는 데 사용됩니다.

conio.h 패키지는 clear screen, getch ​​등과 같은 컴파일러 기능에 사용됩니다.

C++에서 조회 테이블을 생성하기 위해 변수 초기화

이 프로그램은 255 크기의 변수 array, resultarray_elements의 3가지 부동 소수점 변수를 사용합니다. 다른 모든 변수는 정수 데이터 유형입니다(PI는 3.1415…..로 정의됨).

배열 변수 arr은 255개의 크기로 선언됩니다. 다른 루프에서 sine_table 변수는 주어진 피크에 대한 사인 값을 저장합니다.

마지막으로 sine_table 변수는 동일한 루프 내부에 인쇄됩니다.

#include <conio.h>
#include <math.h>

#include <iostream>

#define PI 3.14159265

float arr[255], final_result, array_elements;
int index, Deg, sine_table;

int main(void) {
  printf("Enter the degree\n");
  scanf("%d", &Deg);

  printf("Enter the index of total point\n");
  scanf("%d", &index);

  printf("Enter the max range\n");
  int r;
  scanf("%d", &r);

  final_result = Deg / index;

  for (int i = 0; i < index; i++) {
    int sum;
    sum += final_result;
    arr[i] = sum;
  }

  for (int n = 0; n < index; n++) {
    array_elements = (arr[n]);
    sine_table = sin(array_elements * PI / 180) * r;
    printf("%d\t", sine_table);
  }
  getch();
  return (0);
}

결론

이 글을 읽고 룩업 테이블 생성의 모든 개념을 깔끔하게 이해하셨기를 바랍니다. 여기에 제시된 예는 조회 테이블이 프로그램 내에서 생성되고 사용되는 방법에 대한 완전한 개요를 제공합니다.

이 기사를 읽고 나면 프로그램에서 조회 테이블을 사용할 때의 장점과 단점을 이해하게 될 것입니다.

관련 문장 - C++ Table