mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-07 01:53:34 +08:00
tools: add crc32sum
This commit is contained in:
parent
6c1ebe4474
commit
903e21f651
@ -26,6 +26,7 @@ tools-y += e2fsprogs fakeroot findutils firmware-utils flex gengetopt
|
|||||||
tools-y += libressl libtool lzma m4 make-ext4fs missing-macros mkimage
|
tools-y += libressl libtool lzma m4 make-ext4fs missing-macros mkimage
|
||||||
tools-y += mklibs mm-macros mtd-utils mtools ninja padjffs2 patch-image
|
tools-y += mklibs mm-macros mtd-utils mtools ninja padjffs2 patch-image
|
||||||
tools-y += patchelf pkgconf quilt squashfskit4 sstrip zip zlib zstd
|
tools-y += patchelf pkgconf quilt squashfskit4 sstrip zip zlib zstd
|
||||||
|
tools-y += crc32sum
|
||||||
tools-$(BUILD_B43_TOOLS) += b43-tools
|
tools-$(BUILD_B43_TOOLS) += b43-tools
|
||||||
tools-$(BUILD_ISL) += isl
|
tools-$(BUILD_ISL) += isl
|
||||||
tools-$(BUILD_TOOLCHAIN) += expat gmp libelf mpc mpfr
|
tools-$(BUILD_TOOLCHAIN) += expat gmp libelf mpc mpfr
|
||||||
|
23
tools/crc32sum/Makefile
Normal file
23
tools/crc32sum/Makefile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2021 MediaTek Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=crc32sum
|
||||||
|
PKG_VERSION:=1.0
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/host-build.mk
|
||||||
|
|
||||||
|
define Host/Prepare
|
||||||
|
mkdir -p $(HOST_BUILD_DIR)
|
||||||
|
$(CP) -a ./src/* $(HOST_BUILD_DIR)/
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Host/Install
|
||||||
|
$(INSTALL_BIN) $(HOST_BUILD_DIR)/crc32sum $(STAGING_DIR_HOST)/bin/
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call HostBuild))
|
18
tools/crc32sum/src/Makefile
Normal file
18
tools/crc32sum/src/Makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2021 MediaTek Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
all: crc32sum
|
||||||
|
|
||||||
|
crc32sum: crc32sum.c
|
||||||
|
$(CC) $(CFLAGS) -O2 -ggdb -MD -o $@ $< $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f crc32sum crc32sum.d
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
-include crc32sum.d
|
282
tools/crc32sum/src/crc32sum.c
Normal file
282
tools/crc32sum/src/crc32sum.c
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 MediaTek Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#define SET_BINARY_MODE(_f) _setmode(_fileno(_f, O_BINARY)
|
||||||
|
#else
|
||||||
|
#define SET_BINARY_MODE(_f) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CRC32_LE_POLY_DEFAULT 0xedb88320
|
||||||
|
#define CRC32_BE_POLY_DEFAULT 0x04c11db7
|
||||||
|
#define CRC32_TABLE_ITEMS 256
|
||||||
|
|
||||||
|
static uint32_t crc32_le_calc(uint32_t crc, const uint8_t *data, size_t length,
|
||||||
|
const uint32_t *crc_table)
|
||||||
|
{
|
||||||
|
while (length--)
|
||||||
|
crc = crc_table[(uint8_t)(crc ^ *data++)] ^ (crc >> 8);
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void crc32_le_init(uint32_t *crc_table, uint32_t poly)
|
||||||
|
{
|
||||||
|
uint32_t i, j, v;
|
||||||
|
|
||||||
|
for (i = 0; i < CRC32_TABLE_ITEMS; i++) {
|
||||||
|
v = i;
|
||||||
|
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
v = (v >> 1) ^ ((v & 1) ? poly : 0);
|
||||||
|
|
||||||
|
crc_table[i] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t crc32_be_calc(uint32_t crc, const uint8_t *data, size_t length,
|
||||||
|
const uint32_t *crc_table)
|
||||||
|
{
|
||||||
|
while (length--)
|
||||||
|
crc = crc_table[(uint8_t)((crc >> 24) ^ *data++)] ^ (crc << 8);
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void crc32_be_init(uint32_t *crc_table, uint32_t poly)
|
||||||
|
{
|
||||||
|
uint32_t i, j, v;
|
||||||
|
|
||||||
|
for (i = 0; i < CRC32_TABLE_ITEMS; i++) {
|
||||||
|
v = i << 24;
|
||||||
|
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
v = (v << 1) ^ ((v & (1 << 31)) ? poly : 0);
|
||||||
|
|
||||||
|
crc_table[i] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct crc_funcs {
|
||||||
|
uint32_t poly;
|
||||||
|
|
||||||
|
void (*init)(uint32_t *crc_table, uint32_t poly);
|
||||||
|
uint32_t (*calc)(uint32_t crc, const uint8_t *data, size_t length,
|
||||||
|
const uint32_t *crc_table);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct crc_funcs crc32_le = {
|
||||||
|
.poly = CRC32_LE_POLY_DEFAULT,
|
||||||
|
.init = crc32_le_init,
|
||||||
|
.calc = crc32_le_calc,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct crc_funcs crc32_be = {
|
||||||
|
.poly = CRC32_BE_POLY_DEFAULT,
|
||||||
|
.init = crc32_be_init,
|
||||||
|
.calc = crc32_be_calc,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct crc_funcs *crc32_algo = &crc32_le;
|
||||||
|
static uint32_t crc32_poly;
|
||||||
|
static uint32_t crc32_val;
|
||||||
|
static const char *input_file;
|
||||||
|
static bool output_decimal;
|
||||||
|
static bool no_comp;
|
||||||
|
|
||||||
|
static void err(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
fprintf(stderr, "Error: ");
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(FILE *con, const char *progname, int exitcode)
|
||||||
|
{
|
||||||
|
const char *prog;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(progname);
|
||||||
|
prog = progname + len - 1;
|
||||||
|
|
||||||
|
while (prog > progname) {
|
||||||
|
if (*prog == '\\' || *prog == '/') {
|
||||||
|
prog++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prog--;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(con, "CRC32 checksum tool\n");
|
||||||
|
fprintf(con, "\n");
|
||||||
|
fprintf(con, "Usage: %s [options] <input_file>\n", prog);
|
||||||
|
fprintf(con, "\n");
|
||||||
|
fprintf(con, "Options:\n");
|
||||||
|
fprintf(con, "\t-h display help message\n");
|
||||||
|
fprintf(con, "\t-i <val> crc value for incremental calculation\n");
|
||||||
|
fprintf(con, "\t (default is 0)\n");
|
||||||
|
fprintf(con, "\t-p <val> polynomial for calculation\n");
|
||||||
|
fprintf(con, "\t (default is 0x%08x for LE, 0x%08x for BE)\n",
|
||||||
|
crc32_le.poly, crc32_be.poly);
|
||||||
|
fprintf(con, "\t-b use big-endian mode\n");
|
||||||
|
fprintf(con, "\t-n do not use one's complement\n");
|
||||||
|
fprintf(con, "\t-d use decimal output\n");
|
||||||
|
fprintf(con, "\n");
|
||||||
|
|
||||||
|
exit(exitcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_args(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
static const char *optstring = "i:p:bndh";
|
||||||
|
|
||||||
|
opterr = 0;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, optstring)) >= 0) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'i':
|
||||||
|
if (!isxdigit(optarg[0])) {
|
||||||
|
err("Invalid crc value - %s\n", optarg);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc32_val = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
if (!isxdigit(optarg[0])) {
|
||||||
|
err("Invalid polynomial value - %s\n", optarg);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc32_poly = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
crc32_algo = &crc32_be;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
no_comp = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
output_decimal = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
usage(stdout, argv[0], 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage(stderr, argv[0], EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!crc32_poly)
|
||||||
|
crc32_poly = crc32_algo->poly;
|
||||||
|
|
||||||
|
if (optind >= argc)
|
||||||
|
input_file = "-";
|
||||||
|
else
|
||||||
|
input_file = argv[optind];
|
||||||
|
|
||||||
|
if (!input_file[0]) {
|
||||||
|
err("Input file must not be empty\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int crc32_calc(void)
|
||||||
|
{
|
||||||
|
uint32_t crc_table[CRC32_TABLE_ITEMS];
|
||||||
|
bool using_stdin = false;
|
||||||
|
uint8_t buf[4096];
|
||||||
|
size_t size;
|
||||||
|
int ret, i;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (!strcmp(input_file, "-")) {
|
||||||
|
SET_BINARY_MODE(stdin);
|
||||||
|
using_stdin = true;
|
||||||
|
f = stdin;
|
||||||
|
} else {
|
||||||
|
f = fopen(input_file, "rb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
err("Failed to open file '%s'\n", input_file);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc32_algo->init(crc_table, crc32_poly);
|
||||||
|
|
||||||
|
if (!no_comp)
|
||||||
|
crc32_val ^= 0xffffffff;
|
||||||
|
|
||||||
|
do {
|
||||||
|
size = fread(buf, 1, sizeof(buf), f);
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
crc32_val = crc32_algo->calc(crc32_val, buf, size,
|
||||||
|
crc_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < sizeof(buf)) {
|
||||||
|
ret = ferror(f);
|
||||||
|
|
||||||
|
if (!ret && feof(f))
|
||||||
|
break;
|
||||||
|
|
||||||
|
err("Error while reading file: %d\n", ret);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
if (!using_stdin)
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!no_comp)
|
||||||
|
crc32_val ^= 0xffffffff;
|
||||||
|
|
||||||
|
if (output_decimal)
|
||||||
|
printf("%u\n", crc32_val);
|
||||||
|
else
|
||||||
|
printf("%08x\n", crc32_val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (parse_args(argc, argv))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return crc32_calc();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user