//#define __MATRIX_MAIN_ENABLE__ // define 되어 있으면 main 함수가 포함된다. Unit test 시에 사용 #ifndef __MATRIX_MAIN_ENABLE__ #include "stdafx.h" #else #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> #define sys_err printf #define sys_log printf #endif #include "matrix_card.h" #define ROW(rows, i) ((rows >> ((4 - i - 1) * 8)) & 0x000000FF) #define COL(cols, i) ((cols >> ((4 - i - 1) * 8)) & 0x000000FF) const static int MAX_ROWS = 6; const static int MAX_COLS = 8; const static unsigned int MAX_LENS = (MAX_ROWS * MAX_COLS * 2); const static unsigned int MAX_LENE = (MAX_LENS * 2); const static int ASLENGTH = 8; bool EncodeMatrix(const char* szsrc, const char* szpwd, char* lpdes, const unsigned int usize) { int nlen = strlen(szsrc); int i; if (strlen(szsrc) != MAX_LENS || strlen(szpwd) != MAX_LENS || lpdes == NULL || usize < (MAX_LENE + 1)) return false; memset(lpdes, 0, usize); for (i = 0; i < nlen; i++) { char sc = szsrc[i]; char pc = szpwd[i]; char dc = sc ^ pc; char szhex[3]; snprintf(szhex, sizeof(szhex), "%02X", dc); strlcat(lpdes, szhex, usize); } return (i == nlen) ? true : false; } bool DecodeMatrix(const char* szsrc, const char* szpwd, char* lpdes, const unsigned int usize) { int nlen = strlen(szpwd); int i; if (strlen(szsrc) != MAX_LENE || strlen(szpwd) != MAX_LENS || lpdes == NULL || usize < (MAX_LENS + 1)) return false; memset(lpdes, 0, usize); char szhex[] = { "0123456789ABCDEF" }; for (i = 0; i < nlen; i++) { char sc1 = szsrc[i*2]; char sc2 = szsrc[i*2+1]; char pc = szpwd[i]; char sn1 = (char)(strchr(szhex, sc1) - szhex); char sn2 = (char)(strchr(szhex, sc2) - szhex); char dc = (sn1 * 16 + sn2) ^ pc; lpdes[i] = dc; } return (i == nlen) ? true : false; } void MatrixCardRndCoordinate(unsigned int & rows, unsigned int & cols) { for (unsigned int i = 0; i < (ASLENGTH >> 1); i++) { rows |= ((Random::get(0, MAX_ROWS - 1)) & 0x000000FF) << ((4 - i - 1) * 8); cols |= ((Random::get(0, MAX_COLS - 1)) & 0x000000FF) << ((4 - i - 1) * 8); } } bool ChkCoordinate(const unsigned int rows, const unsigned int cols, const char* matrix, const char* answer) { unsigned int max_lens = strlen(matrix); int answer_lens = strlen(answer); if (max_lens != MAX_LENS || answer_lens != ASLENGTH) { sys_err("MATRIX_CARD: length error matrix %d answer %d", max_lens, answer_lens); return false; } bool fResult = true; unsigned short * pmatrix = (unsigned short *)matrix; unsigned short * panswer = (unsigned short *)answer; for (unsigned int i = 0; i < (ASLENGTH >> 1); i++) { if (*(pmatrix + (ROW(rows, i) * MAX_COLS + COL(cols, i))) != *(panswer + i)) { fResult = false; break; } } return fResult; } bool MatrixCardCheck(const char * src, const char * answer, unsigned int rows, unsigned cols) { const char * szpasswd = "xEwx3Lb5fH2mnPaMh215cHTbCrFCSmh9yQ3FrybwPnD89QkNX4UTA8UdH41LnU4P94UnaeXDTk17dY5DLaSDPAwvEpMUNTxV"; char decode_result[MAX_LENS+1]; DecodeMatrix(src, szpasswd, decode_result, sizeof(decode_result)); sys_log(0, "MatrixCardCheck %c%d %c%d %c%d %c%d answer %s", MATRIX_CARD_ROW(rows, 0) + 'A', MATRIX_CARD_COL(cols, 0) + 1, MATRIX_CARD_ROW(rows, 1) + 'A', MATRIX_CARD_COL(cols, 1) + 1, MATRIX_CARD_ROW(rows, 2) + 'A', MATRIX_CARD_COL(cols, 2) + 1, MATRIX_CARD_ROW(rows, 3) + 'A', MATRIX_CARD_COL(cols, 3) + 1, answer); return ChkCoordinate(rows, cols, decode_result, answer); } #ifdef __MATRIX_MAIN_ENABLE__ void GetRightAnswer(const unsigned int rows, const unsigned int cols, const char* matrix, char* answer, const unsigned int nsize) { if (strlen(matrix) != MAX_LENS || answer == NULL || nsize < (ASLENGTH + 1)) return; unsigned short * pmatrix = (unsigned short *)matrix; unsigned short * panswer = (unsigned short *)answer; memset(answer, 0, nsize); for (unsigned int i = 0; i < (ASLENGTH >> 1); i++) { char sztemp[3] = { 0, 0, 0 }; memcpy(sztemp, (char*)(pmatrix + (ROW(rows, i) * MAX_COLS + COL(cols, i))), 2); strlcat(answer, sztemp, nsize); } } int main(int argc, char* argv[]) { srandomdev(); char* szmatrix = "9Vnppuvv6D8uDmKV9Lbn3ntav6Y86tbMLre7w3DmFc4mTNYEm2UtrppuC9LX6yhYShYTSTCLNC1GwCEV717hTaVYCftMK2xS"; char* szpasswd = "xEwx3Lb5fH2mnPaMh215cHTbCrFCSmh9yQ3FrybwPnD89QkNX4UTA8UdH41LnU4P94UnaeXDTk17dY5DLaSDPAwvEpMUNTxV"; // matrix encode and decode test char encode_result[MAX_LENE + 1], decode_result[MAX_LENS+1]; EncodeMatrix(szmatrix, szpasswd, encode_result, sizeof(encode_result)); printf("Encode result: %s\r\n", encode_result); DecodeMatrix(encode_result, szpasswd, decode_result, sizeof(decode_result)); printf("Decode result: %s\r\n", decode_result); // matrix rand password test unsigned int rand_rows = 0, rand_cols = 0; MatrixCardRndCoordinate(rand_rows, rand_cols); // get rand position of matrix // display rand position printf("%c%d %c%d %c%d %c%d\r\n", ROW(rand_rows, 0) + 'A', COL(rand_cols, 0) + 1, \ ROW(rand_rows, 1) + 'A', COL(rand_cols, 1) + 1, \ ROW(rand_rows, 2) + 'A', COL(rand_cols, 2) + 1, \ ROW(rand_rows, 3) + 'A', COL(rand_cols, 3) + 1); char answer[9]; GetRightAnswer(rand_rows, rand_cols, szmatrix, answer, sizeof(answer)); // get right answer for test, release not need. printf("Answer: %s\r\n", answer); bool f = ChkCoordinate(rand_rows, rand_cols, szmatrix, answer); // check answer printf("Result: %s\n", (f) ? "true" : "false"); return 1; } #endif