diff --git a/32/CMakeLists.txt b/32/CMakeLists.txt deleted file mode 100644 index 307faf0..0000000 --- a/32/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.0.0) -project(base1432 VERSION 2.0) -SET(CMAKE_BUILD_TYPE "Release") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native") - -add_library(base1432 STATIC base14.c) -add_library(base14 SHARED base14.c) - -INSTALL(TARGETS base14 LIBRARY DESTINATION lib) -INSTALL(FILES base14.h DESTINATION include) \ No newline at end of file diff --git a/32/base14.h b/32/base14.h deleted file mode 100644 index 2d1f7da..0000000 --- a/32/base14.h +++ /dev/null @@ -1,13 +0,0 @@ -//base1432le.h -//fumiama 20210408 -#include - -#define B14BUFSIZ 1024*1024 // 1M -struct LENDAT { - uint8_t* data; - int32_t len; -}; -typedef struct LENDAT LENDAT; - -LENDAT* encode(const uint8_t* data, const int32_t len); -LENDAT* decode(const uint8_t* data, const int32_t len); diff --git a/64/CMakeLists.txt b/64/CMakeLists.txt deleted file mode 100644 index d6da116..0000000 --- a/64/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.0.0) -project(base1464 VERSION 2.0) -SET(CMAKE_BUILD_TYPE "Release") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native") - -add_library(base1464 STATIC base14.c) -add_library(base14 SHARED base14.c) - -INSTALL(TARGETS base14 LIBRARY DESTINATION lib) -INSTALL(FILES base14.h DESTINATION include) \ No newline at end of file diff --git a/64/base14.h b/64/base14.h deleted file mode 100644 index 9116eed..0000000 --- a/64/base14.h +++ /dev/null @@ -1,13 +0,0 @@ -//base1464le.h -//fumiama 20210408 -#include - -#define B14BUFSIZ 1024*1024 // 1M -struct LENDAT { - uint8_t* data; - int64_t len; -}; -typedef struct LENDAT LENDAT; - -LENDAT* encode(const uint8_t* data, const int64_t len); -LENDAT* decode(const uint8_t* data, const int64_t len); diff --git a/CMakeLists.txt b/CMakeLists.txt index 9384dad..5a736f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.0.0) project(base16384 VERSION 2.0) SET(CMAKE_BUILD_TYPE "Release") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native") add_executable(base16384 base16384.c) @@ -11,13 +12,15 @@ if (${isBigEndian}) endif() IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - add_definitions("-DCPUBIT64") - add_subdirectory("./64") - target_link_libraries(base16384 base1464) + add_library(b1464 STATIC base1464.c base14.c) + add_library(b14 SHARED base1464.c base14.c) + target_link_libraries(base16384 b1464) ELSE() - add_definitions("-DCPUBIT32") - add_subdirectory("./32") - target_link_libraries(base16384 base1432) + add_library(b1432 STATIC base1432.c base14.c) + add_library(b14 SHARED base1432.c base14.c) + target_link_libraries(base16384 b1432) ENDIF() -INSTALL(TARGETS base16384 RUNTIME DESTINATION bin) \ No newline at end of file +INSTALL(TARGETS base16384 RUNTIME DESTINATION bin) +INSTALL(TARGETS b14 LIBRARY DESTINATION lib) +INSTALL(FILES base14.h DESTINATION include) \ No newline at end of file diff --git a/base14.c b/base14.c new file mode 100644 index 0000000..0db1263 --- /dev/null +++ b/base14.c @@ -0,0 +1,32 @@ +#include "base14.h" + +int encode_len(int dlen) { + int outlen = dlen / 7 * 8; + int offset = dlen % 7; + switch(offset) { // 算上偏移标志字符占用的2字节 + case 0: break; + case 1: outlen += 4; break; + case 2: + case 3: outlen += 6; break; + case 4: + case 5: outlen += 8; break; + case 6: outlen += 10; break; + default: break; + } + return outlen + 8; // 冗余的8B用于可能的结尾的覆盖 +} + +int decode_len(int dlen, int offset) { + int outlen = dlen; + switch(offset) { // 算上偏移标志字符占用的2字节 + case 0: break; + case 1: outlen -= 4; break; + case 2: + case 3: outlen -= 6; break; + case 4: + case 5: outlen -= 8; break; + case 6: outlen -= 10; break; + default: break; + } + return outlen / 8 * 7 + offset + 1; // 多出1字节用于循环覆盖 +} diff --git a/base14.h b/base14.h new file mode 100644 index 0000000..598f7a7 --- /dev/null +++ b/base14.h @@ -0,0 +1,12 @@ +// base14.h +// fumiama 20220319 + +// encode_len calc min buf size to fill encode result +int encode_len(int dlen); +// decode_len calc min buf size to fill decode result +int decode_len(int dlen, int offset); + +// encode data and write result into buf +int encode(const char* data, int dlen, char* buf, int blen); +// decode data and write result into buf +int decode(const char* data, int dlen, char* buf, int blen); diff --git a/32/base14.c b/base1432.c similarity index 69% rename from 32/base14.c rename to base1432.c index 4523be7..81eba1a 100644 --- a/32/base14.c +++ b/base1432.c @@ -1,5 +1,5 @@ -//base1432le.c -//fumiama 20210408 +// base1432.c +// fumiama 20220319 #include #include #ifdef __linux__ @@ -37,17 +37,12 @@ #endif #include "base14.h" -//#define DEBUG +// #define DEBUG -#ifndef new - #define new malloc -#endif - -LENDAT* encode(const uint8_t* data, const int32_t len) { - LENDAT* encd = (LENDAT*)new(sizeof(LENDAT)); - int32_t outlen = len / 7 * 8; - uint8_t offset = len % 7; - switch(offset) { //算上偏移标志字符占用的2字节 +int encode(const char* data, int dlen, char* buf, int blen) { + int outlen = dlen / 7 * 8; + int offset = dlen % 7; + switch(offset) { // 算上偏移标志字符占用的2字节 case 0: break; case 1: outlen += 4; break; case 2: @@ -60,12 +55,10 @@ LENDAT* encode(const uint8_t* data, const int32_t len) { #ifdef DEBUG printf("outlen: %llu, offset: %u, malloc: %llu\n", outlen, offset, outlen + 8); #endif - encd->data = (uint8_t*)new(outlen + 8); //冗余的8B用于可能的结尾的覆盖 - encd->len = outlen; - uint32_t* vals = (uint32_t*)(encd->data); + uint32_t* vals = (uint32_t*)buf; uint32_t n = 0; int32_t i = 0; - for(; i <= len - 7; i += 7) { + for(; i <= dlen - 7; i += 7) { register uint32_t sum = 0; register uint32_t shift = htobe32(*(uint32_t*)(data+i)); sum |= (shift>>2) & 0x3fff0000; @@ -118,19 +111,18 @@ LENDAT* encode(const uint8_t* data, const int32_t len) { #else vals[n] = sum; #endif - encd->data[outlen - 2] = '='; - encd->data[outlen - 1] = offset; + buf[outlen - 2] = '='; + buf[outlen - 1] = offset; } - return encd; + return outlen; } -LENDAT* decode(const uint8_t* data, const int32_t len) { - LENDAT* decd = (LENDAT*)new(sizeof(LENDAT)); - int32_t outlen = len; - uint8_t offset = 0; - if(data[len-2] == '=') { - offset = data[len-1]; - switch(offset) { //算上偏移标志字符占用的2字节 +int decode(const char* data, int dlen, char* buf, int blen) { + int outlen = dlen; + int offset = 0; + if(data[dlen-2] == '=') { + offset = data[dlen-1]; + switch(offset) { // 算上偏移标志字符占用的2字节 case 0: break; case 1: outlen -= 4; break; case 2: @@ -142,12 +134,10 @@ LENDAT* decode(const uint8_t* data, const int32_t len) { } } outlen = outlen / 8 * 7 + offset; - decd->data = (uint8_t*)new(outlen+1); //多出1字节用于循环覆盖 - decd->len = outlen; uint32_t* vals = (uint32_t*)data; uint32_t n = 0; int32_t i = 0; - for(; i <= outlen - 7; i+=7) { //n实际每次自增2 + for(; i <= outlen - 7; i+=7) { // n实际每次自增2 register uint32_t sum = 0; register uint32_t shift = htobe32(vals[n++]) - 0x4e004e00; shift <<= 2; @@ -156,44 +146,44 @@ LENDAT* decode(const uint8_t* data, const int32_t len) { sum |= shift & 0x0003fff0; shift = htobe32(vals[n++]) - 0x4e004e00; sum |= shift >> 26; - *(uint32_t*)(decd->data+i) = be32toh(sum); + *(uint32_t*)(buf+i) = be32toh(sum); sum = 0; shift <<= 6; sum |= shift & 0xffc00000; shift <<= 2; sum |= shift & 0x003fff00; - *(uint32_t*)(decd->data+i+4) = be32toh(sum); + *(uint32_t*)(buf+i+4) = be32toh(sum); } if(offset--) { - //这里有读取越界 + // 这里有读取越界 #ifdef WORDS_BIGENDIAN register uint32_t sum = __builtin_bswap32(vals[n++]); #else register uint32_t sum = vals[n++]; #endif sum -= 0x0000004e; - decd->data[i++] = ((sum & 0x0000003f) << 2) | ((sum & 0x0000c000) >> 14); + buf[i++] = ((sum & 0x0000003f) << 2) | ((sum & 0x0000c000) >> 14); if(offset--) { sum -= 0x004e0000; - decd->data[i++] = ((sum & 0x00003f00) >> 6) | ((sum & 0x00300000) >> 20); + buf[i++] = ((sum & 0x00003f00) >> 6) | ((sum & 0x00300000) >> 20); if(offset--) { - decd->data[i++] = ((sum & 0x000f0000) >> 12) | ((sum & 0xf0000000) >> 28); + buf[i++] = ((sum & 0x000f0000) >> 12) | ((sum & 0xf0000000) >> 28); if(offset--) { - decd->data[i++] = (sum & 0x0f000000) >> 20; - //这里有读取越界 + buf[i++] = (sum & 0x0f000000) >> 20; + // 这里有读取越界 sum = vals[n]; sum -= 0x0000004e; - decd->data[i++] |= (sum & 0x0000003c) >> 2; + buf[i++] |= (sum & 0x0000003c) >> 2; if(offset--) { - decd->data[i++] = ((sum & 0x00000003) << 6) | ((sum & 0x0000fc00) >> 10); + buf[i++] = ((sum & 0x00000003) << 6) | ((sum & 0x0000fc00) >> 10); if(offset--) { sum -= 0x004e0000; - decd->data[i] = ((sum & 0x00000300) >> 2) | ((sum & 0x003f0000) >> 16); + buf[i] = ((sum & 0x00000300) >> 2) | ((sum & 0x003f0000) >> 16); } } } } } } - return decd; + return outlen; } diff --git a/64/base14.c b/base1464.c similarity index 71% rename from 64/base14.c rename to base1464.c index e31cf65..8be83db 100644 --- a/64/base14.c +++ b/base1464.c @@ -1,5 +1,5 @@ -//base14.c -//fumiama 20211029 +// base1464.c +// fumiama 20211029 #include #include #ifdef __linux__ @@ -44,17 +44,12 @@ #endif #include "base14.h" -//#define DEBUG +// #define DEBUG -#ifndef new - #define new malloc -#endif - -LENDAT* encode(const uint8_t* data, const int64_t len) { - LENDAT* encd = (LENDAT*)new(sizeof(LENDAT)); - int64_t outlen = len / 7 * 8; - uint8_t offset = len % 7; - switch(offset) { //算上偏移标志字符占用的2字节 +int encode(const char* data, int dlen, char* buf, int blen) { + int outlen = dlen / 7 * 8; + int offset = dlen % 7; + switch(offset) { // 算上偏移标志字符占用的2字节 case 0: break; case 1: outlen += 4; break; case 2: @@ -67,14 +62,12 @@ LENDAT* encode(const uint8_t* data, const int64_t len) { #ifdef DEBUG printf("outlen: %llu, offset: %u, malloc: %llu\n", outlen, offset, outlen + 8); #endif - encd->data = (uint8_t*)new(outlen + 8); //冗余的8B用于可能的结尾的覆盖 - encd->len = outlen; - uint64_t* vals = (uint64_t*)(encd->data); + uint64_t* vals = (uint64_t*)buf; uint64_t n = 0; int64_t i = 0; - for(; i <= len - 7; i += 7) { + for(; i <= dlen - 7; i += 7) { register uint64_t sum = 0; - register uint64_t shift = htobe64(*(uint64_t*)(data+i))>>2; //这里有读取越界 + register uint64_t shift = htobe64(*(uint64_t*)(data+i))>>2; // 这里有读取越界 sum |= shift & 0x3fff000000000000; shift >>= 2; sum |= shift & 0x00003fff00000000; @@ -88,7 +81,7 @@ LENDAT* encode(const uint8_t* data, const int64_t len) { printf("i: %llu, add sum: %016llx\n", i, sum); #endif } - uint8_t o = offset; + int o = offset; if(o--) { register uint64_t sum = 0x000000000000003f & (data[i] >> 2); sum |= ((uint64_t)data[i] << 14) & 0x000000000000c000; @@ -121,19 +114,18 @@ LENDAT* encode(const uint8_t* data, const int64_t len) { #ifdef DEBUG printf("i: %llu, add sum: %016llx\n", i, sum); #endif - encd->data[outlen - 2] = '='; - encd->data[outlen - 1] = offset; + buf[outlen - 2] = '='; + buf[outlen - 1] = offset; } - return encd; + return outlen; } -LENDAT* decode(const uint8_t* data, const int64_t len) { - LENDAT* decd = (LENDAT*)new(sizeof(LENDAT)); - int64_t outlen = len; - uint8_t offset = 0; - if(data[len-2] == '=') { - offset = data[len-1]; - switch(offset) { //算上偏移标志字符占用的2字节 +int decode(const char* data, int dlen, char* buf, int blen) { + int outlen = dlen; + int offset = 0; + if(data[dlen-2] == '=') { + offset = data[dlen-1]; + switch(offset) { // 算上偏移标志字符占用的2字节 case 0: break; case 1: outlen -= 4; break; case 2: @@ -145,8 +137,6 @@ LENDAT* decode(const uint8_t* data, const int64_t len) { } } outlen = outlen / 8 * 7 + offset; - decd->data = (uint8_t*)new(outlen+1); //多出1字节用于循环覆盖 - decd->len = outlen; uint64_t* vals = (uint64_t*)data; uint64_t n = 0; int64_t i = 0; @@ -161,37 +151,37 @@ LENDAT* decode(const uint8_t* data, const int64_t len) { sum |= shift & 0x0000000fffc00000; shift <<= 2; sum |= shift & 0x00000000003fff00; - *(uint64_t*)(decd->data+i) = be64toh(sum); + *(uint64_t*)(buf+i) = be64toh(sum); #ifdef DEBUG printf("i: %llu, add sum: %016llx\n", i, sum); #endif } if(offset--) { - //这里有读取越界 + // 这里有读取越界 #ifdef WORDS_BIGENDIAN register uint64_t sum = __builtin_bswap64(vals[n]) - 0x000000000000004e; #else register uint64_t sum = vals[n] - 0x000000000000004e; #endif - decd->data[i++] = ((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14); + buf[i++] = ((sum & 0x000000000000003f) << 2) | ((sum & 0x000000000000c000) >> 14); if(offset--) { sum -= 0x00000000004e0000; - decd->data[i++] = ((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20); + buf[i++] = ((sum & 0x0000000000003f00) >> 6) | ((sum & 0x0000000000300000) >> 20); if(offset--) { - decd->data[i++] = ((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28); + buf[i++] = ((sum & 0x00000000000f0000) >> 12) | ((sum & 0x00000000f0000000) >> 28); if(offset--) { sum -= 0x0000004e00000000; - decd->data[i++] = ((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34); + buf[i++] = ((sum & 0x000000000f000000) >> 20) | ((sum & 0x0000003c00000000) >> 34); if(offset--) { - decd->data[i++] = ((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42); + buf[i++] = ((sum & 0x0000000300000000) >> 26) | ((sum & 0x0000fc0000000000) >> 42); if(offset--) { sum -= 0x004e000000000000; - decd->data[i] = ((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48); + buf[i] = ((sum & 0x0000030000000000) >> 34) | ((sum & 0x003f000000000000) >> 48); } } } } } } - return decd; + return outlen; } diff --git a/base16384.c b/base16384.c index 03c4e98..766621e 100644 --- a/base16384.c +++ b/base16384.c @@ -1,38 +1,63 @@ #include #include +#include #include #ifdef __WINNT__ #include #endif -#include "base16384.h" +#include "base14.h" + +static off_t get_file_size(const char* filepath) { + struct stat statbuf; + return stat(filepath, &statbuf)?-1:statbuf.st_size; +} void encode_file(const char* input, const char* output) { + off_t inputsize = get_file_size(input); + if(inputsize < 0) { + puts("Get file size error!"); + return; + } FILE* fp = NULL; fp = fopen(input, "rb"); - if(fp) { - FILE* fpo = NULL; - fpo = fopen(output, "wb"); - if(fpo) { - uint8_t* bufi = (uint8_t*)malloc(B14BUFSIZ/7*7); - if(bufi) { - int cnt = 0; - fputc(0xFE, fpo); - fputc(0xFF, fpo); - while((cnt = fread(bufi, sizeof(uint8_t), B14BUFSIZ/7*7, fp))) { - LENDAT* ld = encode(bufi, cnt); - if(fwrite(ld->data, ld->len, 1, fpo) <= 0) { - puts("Write file error!"); - exit(EXIT_FAILURE); - } - free(ld->data); - free(ld); - } - free(bufi); - } else puts("Allocate input buffer error!"); - fclose(fpo); - } else puts("Open output file error!"); + if(!fp) { + puts("Open input file error!"); + return; + } + FILE* fpo = NULL; + fpo = fopen(output, "wb"); + if(!fpo) { + puts("Open output file error!"); + return; + } + if(inputsize > BUFSIZ*1024) inputsize = BUFSIZ*1024/7*7; // big file + char* bufi = (char*)malloc(inputsize); + if(!bufi) { + puts("Allocate input buffer error!"); + return; + } + int outputsize = encode_len(inputsize)+16; + char* bufo = (char*)malloc(outputsize); + if(!bufo) { + puts("Allocate output buffer error!"); + return; + } + size_t cnt = 0; + fputc(0xFE, fpo); + fputc(0xFF, fpo); + while((cnt = fread(bufi, sizeof(char), inputsize, fp))) { + int n = encode(bufi, cnt, bufo, outputsize); + if(fwrite(bufo, n, 1, fpo) <= 0) { + puts("Write file error!"); + return; + } + } + /* 由操作系统负责释放资源 + free(bufo); + free(bufi); + fclose(fpo); fclose(fp); - } else puts("Open input file error!"); + 以缩短程序运行时间 */ } void rm_head(FILE* fp) { @@ -51,36 +76,55 @@ static int is_next_end(FILE* fp) { } void decode_file(const char* input, const char* output) { + off_t inputsize = get_file_size(input); + if(inputsize < 0) { + puts("Get file size error!"); + return; + } FILE* fp = NULL; fp = fopen(input, "rb"); - if(fp) { - FILE* fpo = NULL; - fpo = fopen(output, "wb"); - if(fpo) { - uint8_t* bufi = (uint8_t*)malloc(B14BUFSIZ/8*8 + 2); //+2避免漏检结束偏移标志 - if(bufi) { - int cnt = 0; - int end = 0; - rm_head(fp); - while((cnt = fread(bufi, sizeof(uint8_t), B14BUFSIZ/8*8, fp))) { - if((end = is_next_end(fp))) { - bufi[cnt++] = '='; - bufi[cnt++] = end; - } - LENDAT* ld = decode(bufi, cnt); - if(fwrite(ld->data, ld->len, 1, fpo) <= 0) { - puts("Write file error!"); - exit(EXIT_FAILURE); - } - free(ld->data); - free(ld); - } - free(bufi); - } else puts("Allocate input buffer error!"); - fclose(fpo); - } else puts("Open output file error!"); + if(!fp) { + puts("Open input file error!"); + return; + } + FILE* fpo = NULL; + fpo = fopen(output, "wb"); + if(!fpo) { + puts("Open output file error!"); + return; + } + if(inputsize > BUFSIZ*1024) inputsize = BUFSIZ*1024/8*8; // big file + char* bufi = (char*)malloc(inputsize+2); // +2避免漏检结束偏移标志 + if(!bufi) { + puts("Allocate input buffer error!"); + return; + } + int outputsize = decode_len(inputsize, 0)+16; + char* bufo = (char*)malloc(outputsize); + if(!bufo) { + puts("Allocate output buffer error!"); + return; + } + int cnt = 0; + int end = 0; + rm_head(fp); + while((cnt = fread(bufi, sizeof(char), inputsize, fp))) { + if((end = is_next_end(fp))) { + bufi[cnt++] = '='; + bufi[cnt++] = end; + } + int n = decode(bufi, cnt, bufo, outputsize); + if(fwrite(bufo, n, 1, fpo) <= 0) { + puts("Write file error!"); + return; + } + } + /* 由操作系统负责释放资源 + free(bufo); + free(bufi); + fclose(fpo); fclose(fp); - } else puts("Open input file error!"); + 以缩短程序运行时间 */ } #ifndef __WINNT__ @@ -93,27 +137,26 @@ unsigned long get_start_ms() { #define CHOICE argv[1][1] int main(int argc, char** argv) { - if(argc == 4) { - #if defined(__WINNT__) - clock_t t = clock(); - #else - unsigned long t = get_start_ms(); - #endif - switch(CHOICE){ - case 'e': encode_file(argv[2], argv[3]); break; - case 'd': decode_file(argv[2], argv[3]); break; - default: break; - } - #if defined(__WINNT__) - printf("spend time: %lums\n", clock() - t); - #else - printf("spend time: %lums\n", get_start_ms() - t); - #endif - } else { + if(argc != 4) { fputs("Usage: -[e|d] \n", stderr); fputs("\t-e encode\n", stderr); fputs("\t-d decode\n", stderr); exit(EXIT_FAILURE); } + #ifdef __WINNT__ + clock_t t = clock(); + #else + unsigned long t = get_start_ms(); + #endif + switch(CHOICE) { + case 'e': encode_file(argv[2], argv[3]); break; + case 'd': decode_file(argv[2], argv[3]); break; + default: break; + } + #ifdef __WINNT__ + printf("spend time: %lums\n", clock() - t); + #else + printf("spend time: %lums\n", get_start_ms() - t); + #endif return 0; } diff --git a/base16384.h b/base16384.h deleted file mode 100644 index 4fa5b3b..0000000 --- a/base16384.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef CPUBIT32 - #ifndef CPUBIT64 - #define CPUBIT32 - #endif -#endif -#ifdef CPUBIT32 - #include "./32/base14.h" -#endif -#ifdef CPUBIT64 - #include "./64/base14.h" -#endif