Init
This commit is contained in:
parent
f161bcdfab
commit
87fa30640f
179
APP/main.c
179
APP/main.c
|
|
@ -230,15 +230,11 @@ uint32_t calculate_file_crc32_full(const char *filename, int verbose) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Записывает размер данных и CRC32 в файл
|
* @brief Записывает CRC32 в последние 4 байта файла
|
||||||
* Размер данных (file_size - 4) записывается по смещению 256 байт от конца файла
|
|
||||||
* CRC32 записывается в последние 4 байта файла
|
|
||||||
*/
|
*/
|
||||||
int write_crc32_to_file(const char *filename, uint32_t crc_value, int verbose) {
|
int write_crc32_to_file(const char *filename, uint32_t crc_value, int verbose) {
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
long file_size;
|
long file_size;
|
||||||
long data_size;
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
file = fopen(filename, "rb+");
|
file = fopen(filename, "rb+");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
|
|
@ -246,7 +242,6 @@ int write_crc32_to_file(const char *filename, uint32_t crc_value, int verbose) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получаем размер файла
|
|
||||||
if (fseek(file, 0, SEEK_END) != 0) {
|
if (fseek(file, 0, SEEK_END) != 0) {
|
||||||
perror("Failed to seek to end");
|
perror("Failed to seek to end");
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
@ -260,70 +255,11 @@ int write_crc32_to_file(const char *filename, uint32_t crc_value, int verbose) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_size = file_size - 4; // Размер данных без CRC
|
// Перемещаемся на позицию последних 4 байт
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
printf("File size: %ld bytes\n", file_size);
|
|
||||||
printf("Data size (without CRC): %ld bytes (0x%lX)\n", data_size, data_size);
|
|
||||||
printf("CRC value: 0x%08X (%u)\n", crc_value, crc_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================
|
|
||||||
// 1. Записываем размер данных по смещению 256 байт от конца файла
|
|
||||||
// ==============================================
|
|
||||||
long data_size_offset = file_size - 256; // Позиция для размера данных (ровно 256 байт от конца)
|
|
||||||
|
|
||||||
// Проверяем, что позиция не отрицательная и не перекрывается с CRC
|
|
||||||
if (data_size_offset < 0) {
|
|
||||||
fprintf(stderr, "Warning: File too small, cannot write data size at offset 256 from end\n");
|
|
||||||
fprintf(stderr, "File size: %ld bytes, need at least 256 bytes\n", file_size);
|
|
||||||
if (verbose) {
|
|
||||||
printf("Skipping data size write (file too small)\n");
|
|
||||||
}
|
|
||||||
} else if (data_size_offset + 4 > file_size - 4) {
|
|
||||||
fprintf(stderr, "Warning: Data size position overlaps with CRC area\n");
|
|
||||||
fprintf(stderr, "Data size would be at %ld, CRC at %ld\n", data_size_offset, file_size - 4);
|
|
||||||
if (verbose) {
|
|
||||||
printf("Skipping data size write (overlap detected)\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Перемещаемся на позицию для записи размера данных
|
|
||||||
if (fseek(file, data_size_offset, SEEK_SET) != 0) {
|
|
||||||
perror("Failed to seek to data size position");
|
|
||||||
result = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Записываем размер данных в little-endian порядке (4 байта для 32-битного размера)
|
|
||||||
uint8_t size_bytes[4];
|
|
||||||
size_bytes[0] = (data_size >> 0) & 0xFF;
|
|
||||||
size_bytes[1] = (data_size >> 8) & 0xFF;
|
|
||||||
size_bytes[2] = (data_size >> 16) & 0xFF;
|
|
||||||
size_bytes[3] = (data_size >> 24) & 0xFF;
|
|
||||||
|
|
||||||
size_t bytes_written = fwrite(size_bytes, 1, 4, file);
|
|
||||||
if (bytes_written != 4) {
|
|
||||||
fprintf(stderr, "Failed to write data size to file\n");
|
|
||||||
result = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
printf("\nData size written: %ld bytes (0x%lX)\n", data_size, data_size);
|
|
||||||
printf(" Position: %ld (0x%lX) bytes from start\n", data_size_offset, data_size_offset);
|
|
||||||
printf(" Distance from end: %ld bytes (exactly 256 bytes)\n", file_size - data_size_offset);
|
|
||||||
printf(" Bytes written (LE 32-bit): %02X %02X %02X %02X\n",
|
|
||||||
size_bytes[0], size_bytes[1], size_bytes[2], size_bytes[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================
|
|
||||||
// 2. Записываем CRC в последние 4 байта файла
|
|
||||||
// ==============================================
|
|
||||||
if (fseek(file, file_size - 4, SEEK_SET) != 0) {
|
if (fseek(file, file_size - 4, SEEK_SET) != 0) {
|
||||||
perror("Failed to seek to CRC position");
|
perror("Failed to seek to CRC position");
|
||||||
result = -1;
|
fclose(file);
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Записываем CRC в little-endian порядке
|
// Записываем CRC в little-endian порядке
|
||||||
|
|
@ -336,34 +272,29 @@ int write_crc32_to_file(const char *filename, uint32_t crc_value, int verbose) {
|
||||||
size_t bytes_written = fwrite(crc_bytes, 1, 4, file);
|
size_t bytes_written = fwrite(crc_bytes, 1, 4, file);
|
||||||
if (bytes_written != 4) {
|
if (bytes_written != 4) {
|
||||||
fprintf(stderr, "Failed to write CRC to file\n");
|
fprintf(stderr, "Failed to write CRC to file\n");
|
||||||
result = -1;
|
fclose(file);
|
||||||
goto cleanup;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("\nCRC32 value written: 0x%08X (%u)\n", crc_value, crc_value);
|
printf("CRC32 value written: 0x%08X (%u)\n", crc_value, crc_value);
|
||||||
printf(" Position: %ld-%ld (last 4 bytes)\n", file_size - 4, file_size - 1);
|
printf("Written to bytes: %ld-%ld (last 4 bytes)\n", file_size - 4, file_size - 1);
|
||||||
printf(" Bytes written (LE): %02X %02X %02X %02X\n",
|
|
||||||
crc_bytes[0], crc_bytes[1], crc_bytes[2], crc_bytes[3]);
|
|
||||||
printf("Byte order: little-endian (LSB first)\n");
|
printf("Byte order: little-endian (LSB first)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
return 0;
|
||||||
fclose(file);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Проверяет CRC32, сравнивая вычисленное значение с сохраненным
|
* @brief Проверяет CRC32, сравнивая вычисленное значение с сохраненным
|
||||||
* Также опционально проверяет сохраненный размер данных
|
|
||||||
*/
|
*/
|
||||||
int verify_crc32(const char *filename, int verbose) {
|
int verify_crc32(const char *filename, int verbose) {
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
long file_size;
|
long file_size;
|
||||||
long stored_data_size = 0;
|
|
||||||
uint32_t calculated_crc = 0;
|
uint32_t calculated_crc = 0;
|
||||||
uint32_t stored_crc = 0;
|
uint32_t stored_crc = 0;
|
||||||
int verify_size = 1; // Флаг проверки размера
|
|
||||||
|
|
||||||
file = fopen(filename, "rb");
|
file = fopen(filename, "rb");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
|
|
@ -388,48 +319,7 @@ int verify_crc32(const char *filename, int verbose) {
|
||||||
printf("File size: %ld bytes\n", file_size);
|
printf("File size: %ld bytes\n", file_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==============================================
|
// Читаем сохраненный CRC из последних 4 байт
|
||||||
// 1. Читаем сохраненный размер данных (опционально)
|
|
||||||
// ==============================================
|
|
||||||
long data_size_offset = file_size - 256; // Позиция размера данных (256 байт от конца)
|
|
||||||
if (data_size_offset >= 0 && data_size_offset + 4 <= file_size - 4) {
|
|
||||||
if (fseek(file, data_size_offset, SEEK_SET) != 0) {
|
|
||||||
perror("Failed to seek to stored data size");
|
|
||||||
verify_size = 0;
|
|
||||||
} else {
|
|
||||||
uint8_t size_bytes[4];
|
|
||||||
size_t bytes_read = fread(size_bytes, 1, 4, file);
|
|
||||||
if (bytes_read == 4) {
|
|
||||||
stored_data_size = (long)size_bytes[0] << 0 |
|
|
||||||
(long)size_bytes[1] << 8 |
|
|
||||||
(long)size_bytes[2] << 16 |
|
|
||||||
(long)size_bytes[3] << 24;
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
printf("\nStored data size: %ld bytes (0x%lX) at offset %ld\n",
|
|
||||||
stored_data_size, stored_data_size, data_size_offset);
|
|
||||||
printf(" Distance from end: %ld bytes (exactly 256 bytes)\n", file_size - data_size_offset);
|
|
||||||
printf(" Bytes read (LE 32-bit): %02X %02X %02X %02X\n",
|
|
||||||
size_bytes[0], size_bytes[1], size_bytes[2], size_bytes[3]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
verify_size = 0;
|
|
||||||
if (verbose) {
|
|
||||||
printf("Failed to read stored data size (expected 4 bytes, got %zu)\n", bytes_read);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
verify_size = 0;
|
|
||||||
if (verbose) {
|
|
||||||
printf("\nNo valid data size stored at offset 256 bytes from end\n");
|
|
||||||
printf(" File size: %ld, would need at least %ld bytes\n", file_size, 256 + 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================
|
|
||||||
// 2. Читаем сохраненный CRC из последних 4 байт
|
|
||||||
// ==============================================
|
|
||||||
if (fseek(file, file_size - 4, SEEK_SET) != 0) {
|
if (fseek(file, file_size - 4, SEEK_SET) != 0) {
|
||||||
perror("Failed to seek to stored CRC");
|
perror("Failed to seek to stored CRC");
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
@ -458,48 +348,20 @@ int verify_crc32(const char *filename, int verbose) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
long actual_data_size = file_size - 4;
|
|
||||||
|
|
||||||
// Всегда выводим значения CRC при проверке
|
// Всегда выводим значения CRC при проверке
|
||||||
printf("\n╔════════════════════════════════════════════════════════════╗\n");
|
printf("\n╔════════════════════════════════════════╗\n");
|
||||||
printf("║ CRC32 Verification ║\n");
|
printf("║ CRC32 Verification ║\n");
|
||||||
printf("╠════════════════════════════════════════════════════════════╣\n");
|
printf("╠════════════════════════════════════════╣\n");
|
||||||
printf("║ Stored CRC : 0x%08X (%10u) ║\n", stored_crc, stored_crc);
|
printf("║ Stored CRC : 0x%08X (%10u) ║\n", stored_crc, stored_crc);
|
||||||
printf("║ Calculated CRC : 0x%08X (%10u) ║\n", calculated_crc, calculated_crc);
|
printf("║ Calculated CRC : 0x%08X (%10u) ║\n", calculated_crc, calculated_crc);
|
||||||
|
printf("╚════════════════════════════════════════╝\n");
|
||||||
|
|
||||||
if (verify_size && stored_data_size > 0) {
|
if (calculated_crc == stored_crc) {
|
||||||
printf("╠════════════════════════════════════════════════════════════╣\n");
|
printf("\n✓ VERIFIED: CRC matches! File integrity check passed.\n");
|
||||||
printf("║ Stored data size : %12ld bytes (0x%lX) ║\n", stored_data_size, stored_data_size);
|
|
||||||
printf("║ Actual data size : %12ld bytes (0x%lX) ║\n", actual_data_size, actual_data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("╚════════════════════════════════════════════════════════════╝\n");
|
|
||||||
|
|
||||||
int crc_valid = (calculated_crc == stored_crc);
|
|
||||||
int size_valid = 1;
|
|
||||||
|
|
||||||
if (verify_size && stored_data_size > 0) {
|
|
||||||
size_valid = (actual_data_size == stored_data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crc_valid && size_valid) {
|
|
||||||
printf("\n✓ VERIFIED: CRC matches and data size is correct! File integrity check passed.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (crc_valid && !size_valid) {
|
|
||||||
printf("\n⚠ WARNING: CRC matches but data size mismatch!\n");
|
|
||||||
printf(" Stored size: %ld, Actual size: %ld, Difference: %ld\n",
|
|
||||||
stored_data_size, actual_data_size, actual_data_size - stored_data_size);
|
|
||||||
return 1;
|
|
||||||
} else if (!crc_valid && size_valid) {
|
|
||||||
printf("\n✗ MISMATCH: File is corrupted! CRC does not match (data size OK).\n");
|
|
||||||
printf(" Difference: 0x%08X\n", calculated_crc ^ stored_crc);
|
|
||||||
return 1;
|
|
||||||
} else {
|
} else {
|
||||||
printf("\n✗ MISMATCH: File is corrupted! Both CRC and data size are incorrect!\n");
|
printf("\n✗ MISMATCH: File is corrupted or CRC was not written correctly!\n");
|
||||||
printf(" CRC difference: 0x%08X\n", calculated_crc ^ stored_crc);
|
printf(" Difference: 0x%08X\n", calculated_crc ^ stored_crc);
|
||||||
if (verify_size && stored_data_size > 0) {
|
|
||||||
printf(" Size difference: %ld bytes\n", actual_data_size - stored_data_size);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -704,7 +566,6 @@ void print_usage(const char *program_name) {
|
||||||
printf("\nNote:\n");
|
printf("\nNote:\n");
|
||||||
printf(" For -w and -c operations, CRC is calculated from the first\n");
|
printf(" For -w and -c operations, CRC is calculated from the first\n");
|
||||||
printf(" (file_size - 4) bytes, ignoring the last 4 bytes.\n");
|
printf(" (file_size - 4) bytes, ignoring the last 4 bytes.\n");
|
||||||
printf(" Data size (file_size - 4) is written at offset 256 bytes from end.\n");
|
|
||||||
printf(" For split operation, offset can be specified in decimal or hex (0x prefix).\n");
|
printf(" For split operation, offset can be specified in decimal or hex (0x prefix).\n");
|
||||||
printf(" If output filenames are not specified, default names will be used:\n");
|
printf(" If output filenames are not specified, default names will be used:\n");
|
||||||
printf(" <input>_part1.bin and <input>_part2.bin\n");
|
printf(" <input>_part1.bin and <input>_part2.bin\n");
|
||||||
|
|
@ -870,7 +731,7 @@ int main(int argc, char *argv[]) {
|
||||||
printf("╚════════════════════════════════════════╝\n");
|
printf("╚════════════════════════════════════════╝\n");
|
||||||
|
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
printf("\nStep 2: Writing CRC and data size to file...\n");
|
printf("\nStep 2: Writing CRC to last 4 bytes...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
result = write_crc32_to_file(options.filename, crc_value, options.verbose);
|
result = write_crc32_to_file(options.filename, crc_value, options.verbose);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue