I made this hex dump after being dissatisfied with the free hexdumps out there. The biggest dissatisfaction is that the encodings for the char bytes were not color encoded, just like the hexyl hexdump program.
If you are interested in reading the full background story, you may click on the Medium link: https://medium.com/@tanveerasalim/my-new-colorful-hex-dump-command-a114a043b61c
I tested this hexdump on macOS, Linux, and Windows (CYGWIN) before posting here.
I plan to transform this hex dump into an actual vim-like hex editor, since I could not find a preexisting one of the like of it either.
Instructions For Use:
NAME
tscd
SYNOPSIS
tscd [options] [infile [outfile]]
DESCRIPTION
tscd can create a hexadecimal, decimal, binary, or octal dump of any file. The numerical values will be displayed in a table.To the rightmost of each row will be the ASCII characters corresponding to the ASCII codes in the table.
COLOR ENCODINGS
Below is the Color Encoding Scheme (ASCII):
Red: Non-printable ASCII characters
Orange: Printable (Alphabetic) Characters
Yellow: Base 10 Numerical Digits
Green: ASCII Whitespace Characters
Purple: Punctuation Characters
Gray: NUL byte (00)
OPTIONS
-b Binary dump specified. Each character in file will be translated into its binary number form and displayed in the table.
-c Specify number of columns per row in ASCII code table.
-d Decimal Dump specified. Each character in file will be translated into its binary number form and displayed in the table.
-o Octal Dump specified. Each character in file will be translated into its octal number form and displayed in the table.
-p Print view specified. tscd will simply print the contents of the file directly intointo stdout.
Questions:
Would you actually prefer to use this compared to all other free command-line hexdumps out there, not counting GUI-based ones?
Are you interested in me transforming this program into a vim-like color-encoded hex editor program?
Are you also confident the implementation is portable across Windows (such as on CYGWIN), macOS, and Linux systems?
Implementation:
The link to the GitHub Repository page is: https://github.com/tanveerasalim/TSCD
The complete implementation of the hex dump is below:
#if 0
NOTICE: All the software in this repository
comes with absolutely
NO WARRANTY and provided "as is" basis.
Copyright (C) Tanveer Salim 2018-INFINITY
This software and all other software in
this repository is distributed with a GNU GPL
License v2.0. All are free to copy, share,
distribute, and/or modify this software,
even commercially as long as it compliant
with GNU GPL v2.0 LICENSING terms as well
as the terms of this copyright and license
statement.
All software that was inspired
or is a derivative of this work must have
the exact same LICENSE and copyright permissions.
#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifndef __rsize_t_defined
typedef size_t rsize_t;
#define __rsize_t_defined 1
#endif
#ifdef __RSIZE_MAX__
#define RSIZE_MAX (__RSIZE_MAX__)
#else
#define RSIZE_MAX ( (SIZE_MAX ) >> ( 1 ) )
#endif
#ifndef __uint8_t_defined
typedef unsigned char uint8_t;
#define __uint8_t_defined 1
#endif
#ifndef __uint32_t_defined
typedef unsigned int uint32_t;
#define __uint32_t_defined 1
#endif
#if 0
Bug: When Number of characters in row
is equal to NUM_HEX_ROWS, the last f
in 0xff is deleted and replaced with
a period.
Bug: Number of columns == Number of bytes per row!
NUM_HEX_ROWS == (desired number of columns)/2
default number of columns: 16 to make 16 bytes displayed in total per row
So:
NUM_HEX_ROWS == Number of desired columns
Simple! :D
#endif
//#define NUM_HEX_ROWS_ORIGINAL 16
rsize_t NUM_HEX_ROWS = 16;
rsize_t NUM_BIN_ROWS = 6;
rsize_t NUM_OCT_ROWS = 12;
rsize_t NUM_DEC_ROWS = 12;
rsize_t UTF8_HEX_ROWS = 6;
_Bool bintable_request = 0;
_Bool octtable_request = 0;
_Bool dectable_request = 0;
void colorchar(uint8_t c)
{
if ( c == 0x0 )
{
printf("\e[38;5;244m");
}
else if ( isalpha(c) )
{
printf("\e[38;5;208m");
}
else if ( isdigit(c) )
{
printf("\e[38;5;226m");
}
else if ( !isprint(c) )
{
printf("\e[38;5;196m");
}
else if ( isspace(c) )
{
printf("\e[38;5;40m");
}
else if ( ispunct(c) )
{
// printf("\e[38;5;164m");
printf("\e[38;5;201m");
}
else if ( c < 16 )
{
printf("\e[0;32m");
}
else if ( c >= 16 && c <= 31 )
{
printf("\e[1;35m");
}
}
void resetcolor(void)
{
printf("\033[0m");
}
_Bool isutf8cntrl(uint32_t c)
{
}
void colorutf8(uint8_t * s)
{
uint32_t utf8_hex = 0x00;
uint8_t * s_p = s;
while ( *s_p != 0x00 )
{
utf8_hex += *s_p;
utf8_hex <<= 8;
s_p++;
}
}
void printview(FILE * in, FILE * out,const rsize_t FILE_SIZE)
{
rsize_t i = 0;
uint8_t c = 0;
while ( i < FILE_SIZE )
{
c = fgetc(in);
if ( out != stdout )
{
fprintf(out,"%c",c);
}
else
{
colorchar(c);
printf("%c",c);
resetcolor();
}
i++;
}
}
void reverse(unsigned char s[])
{
for (int i = 0, j = strlen(s)-1; i < j; i++, j--)
{
unsigned char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
unsigned char * print_binary(unsigned char input)
{
static unsigned char s[10];
unsigned char * s_p = &s[0];
while (input > 0)
{
*s_p++ = (unsigned char)((input&1)+'0');
input >>= 1;
}
*s_p = '\0';
reverse(s);
return s;
}
void print_bintable2(FILE * in, FILE * out, unsigned char ASCII[], const rsize_t FILE_SIZE)
{
rsize_t i = 0;
rsize_t u = 0;
unsigned long fpos = 0;
rsize_t j = 0; //need this to create printable ASCII in output
unsigned char c = 0;
while ( i < FILE_SIZE )
{
c = fgetc(in);
#if 0
This printf actually forces printing of ASCII.
#endif
if ( i == 0 )
{ colorchar(c); fprintf(out,"%08x:%c",i,0x20); resetcolor(); }
else if ( (i%NUM_BIN_ROWS) == 0 )
{
fputc(0x20,out);
if ( i >= NUM_BIN_ROWS )
{
fseek(in,-NUM_BIN_ROWS-1,SEEK_CUR);
}
else
{
fseek(in,0,SEEK_SET);
}
u = 0;
while (
u < NUM_BIN_ROWS
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
c = fgetc(in); //catch up to latest row
colorchar(c);
fprintf(out,"\n%08x:%c",i,0x20);
resetcolor();
}
colorchar(c);
fprintf(out,"%08s%c",print_binary(c),0x20);
resetcolor();
#if 0
(i%2 == 0) ? ( fprintf(out,"%08s",print_binary(c)) ) : ( fprintf(out,"%08s%c",print_binary(c),0x20) );
#endif
i++;
// Bug: Write code to place ff and extra spaces to align last ASCII line here
}
if ( i == FILE_SIZE )
{
rsize_t index = i;
while ( index % NUM_BIN_ROWS != 0 )
{
(index%2 == 0)
?
( fprintf(out,"%*c",0x9,0x20) )
:
( fprintf(out,"%*c",0x9,0x20) );
index++;
}
#if 0
This while loop is meant for
a line that is equal to
NUM_BIN_ROWS
#endif
if ( index % NUM_BIN_ROWS == 0 )
{
fputc(0x20,out);
}
}
if ( i == FILE_SIZE && (i%NUM_BIN_ROWS) != 0 )
{
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(i%NUM_BIN_ROWS),SEEK_CUR);
u = 0;
while (
u < ( i%NUM_BIN_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
else // ( i == FILE_SIZE && (i%NUM_BIN_ROWS) == 0 )
{
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(NUM_BIN_ROWS),SEEK_CUR);
u = 0;
while (
u < ( NUM_BIN_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
}
void print_dectable(FILE * in, FILE * out, unsigned char ASCII[], const rsize_t FILE_SIZE)
{
rsize_t i = 0;
rsize_t u = 0;
unsigned long fpos = 0;
rsize_t j = 0; //need this to create printable ASCII in output
unsigned char c = 0;
while ( i < FILE_SIZE )
{
c = fgetc(in);
colorchar(c);
#if 0
This printf actually forces printing of ASCII.
#endif
if ( i == 0 )
{ fprintf(out,"%08x:%c",i,0x20); }
else if ( (i%NUM_DEC_ROWS) == 0 )
{
fputc(0x20,out);
fputc(0x20,out);
if ( i >= NUM_DEC_ROWS )
{
fseek(in,-NUM_DEC_ROWS-1,SEEK_CUR);
}
else
{
fseek(in,0,SEEK_SET);
}
u = 0;
while (
u < NUM_DEC_ROWS
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
c = fgetc(in); //catch up to latest row
colorchar(c);
fprintf(out,"\n%08x:%c",i,0x20);
resetcolor();
}
colorchar(c);
(i%1 != 0) ? ( fprintf(out,"%03u",c) ) : ( fprintf(out,"%c%03u",0x20,c) );
i++;
resetcolor();
// Bug: Write code to place ff and extra spaces to align last ASCII line here
}
if ( i == FILE_SIZE )
{
rsize_t index = i;
while ( index % NUM_DEC_ROWS != 0 )
{
(index%2 == 0)
?
( fprintf(out,"%c%c%c%c",0x20,0x20,0x20,0x20) )
:
( fprintf(out,"%c%c%c%c",0x20,0x20,0x20,0x20) );
index++;
}
#if 0
This while loop is meant for
a line that is equal to
NUM_DEC_ROWS
#endif
if ( index % NUM_DEC_ROWS == 0 )
{
fputc(0x20,out);
}
}
if ( i == FILE_SIZE && (i%NUM_DEC_ROWS) != 0 )
{
fputc(0x20,out);
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(i%NUM_DEC_ROWS),SEEK_CUR);
u = 0;
while (
u < ( i%NUM_DEC_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
else // ( i == FILE_SIZE && (i%NUM_DEC_ROWS) == 0 )
{
fputc(0x20,out);
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(NUM_DEC_ROWS),SEEK_CUR);
u = 0;
while (
u < ( NUM_DEC_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
}
void print_octtable(FILE * in, FILE * out, unsigned char ASCII[], const rsize_t FILE_SIZE)
{
rsize_t i = 0;
rsize_t u = 0;
unsigned long fpos = 0;
rsize_t j = 0; //need this to create printable ASCII in output
unsigned char c = 0;
while ( i < FILE_SIZE )
{
c = fgetc(in);
colorchar(c);
#if 0
This printf actually forces printing of ASCII.
#endif
if ( i == 0 )
{ fprintf(out,"%08x:%c",i,0x20); }
else if ( (i%NUM_OCT_ROWS) == 0 )
{
fputc(0x20,out);
fputc(0x20,out);
if ( i >= NUM_OCT_ROWS )
{
fseek(in,-NUM_OCT_ROWS-1,SEEK_CUR);
}
else
{
fseek(in,0,SEEK_SET);
}
u = 0;
while (
u < NUM_OCT_ROWS
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
c = fgetc(in); //catch up to latest row
colorchar(c);
fprintf(out,"\n%08x:%c",i,0x20);
resetcolor();
}
colorchar(c);
(i%1 != 0) ? ( fprintf(out,"%03o",c) ) : ( fprintf(out,"%c%03o",0x20,c) );
i++;
resetcolor();
// Bug: Write code to place ff and extra spaces to align last ASCII line here
}
if ( i == FILE_SIZE )
{
rsize_t index = i;
while ( index % NUM_OCT_ROWS != 0 )
{
(index%2 == 0)
?
( fprintf(out,"%c%c%c%c",0x20,0x20,0x20,0x20) )
:
( fprintf(out,"%c%c%c%c",0x20,0x20,0x20,0x20) );
index++;
}
#if 0
This while loop is meant for
a line that is equal to
NUM_OCT_ROWS
#endif
if ( index % NUM_OCT_ROWS == 0 )
{
fputc(0x20,out);
}
}
if ( i == FILE_SIZE && (i%NUM_OCT_ROWS) != 0 )
{
fputc(0x20,out);
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(i%NUM_OCT_ROWS),SEEK_CUR);
u = 0;
while (
u < ( i%NUM_OCT_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
else // ( i == FILE_SIZE && (i%NUM_OCT_ROWS) == 0 )
{
fputc(0x20,out);
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(NUM_OCT_ROWS),SEEK_CUR);
u = 0;
while (
u < ( NUM_OCT_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
}
#if 0
For is_utf8cont, assume correct UTF-8 encoding
#endif
#if 0
_Bool is_utf8cont(uint8_t c)
{
//First try to disprove by detecting starting byte
if ( ( c >> 3 ) == 0b11110 )
{
return 0;
}
else if ( ( c >> 4 ) == 0b1110 )
{
return 0;
}
else if ( ( c >> 5 ) == 0b110 )
{
return 0;
}
else if ( ( c >> 7 ) == 0b0 )
{
return 0;
}
return 1;
}
#endif
#if 0
void print_utf8hextable(FILE * in, FILE * out,const rsize_t FILE_SIZE)
{
rsize_t i = 0;
rsize_t utf8i = 0; //for printing actual UTF8 character
static uint32_t utf8_hex = 0x00;
const rsize_t UTF8_STR_SIZE = UTF8_HEX_ROWS*4*sizeof(uint8_t)+1;
static uint8_t utf8_str[UTF8_HEX_ROWS*4*sizeof(uint8_t)+1];
memset_s(utf8_str,UTF8_STR_SIZE,0x00,UTF8_STR_SIZE);
static uint8_t c = 0;
static long utf8_offsets[UTF8_HEX_ROWS];
static long * utf8op;
utf8op = utf8_offsets;
rsize_t cur_utf8char = 0;
while ( i < FILE_SIZE )
{
c = fgetc(in);
#if 0
Print actual hexadecimal representation of UTF-8
character
#endif
if ( i == 0 )
{
printf("%.08x: ",i);
}
else if ( !is_utf8cont(c) ) //starting byte for UTF-8 character
{
printf("%.08x ",utf8_hex);
utf8_hex = 0x00;
*utf8op = ftell(in);
}
else
{
utf8_hex += c;
utf8_hex <<= 8;
utf8_hex &= 0xffffff00
}
if ( utf8i == UTF8_HEX_ROWS )
{
cur_utf8char = ftell(in);
utf8op = utf8_offsets;
rsize_t ic = 0;
while ( utf8op < (utf8_offsets + UTF8_HEX_ROWS) )
{
fseek(in,*utf8op,SEEK_BEG);
while (ic > 0 && !is_utf8cont(c) )
{
c = fgetc(in);
fputc(c,out);
ic++;
}
utf8op++;
ic = 0;
}
memset_s(utf8_offsets,UTF8_HEX_ROWS*sizeof(uint8_t),0x00,UTF8_HEX_ROWS*sizeof(uint8_t));
fseek(in,cur_utf8char,SEEK_BEG);
utf8i = 0;
printf("\n%.08x: ",i);
}
else
{
utf8i++;
}
i++;
}
}
#endif
void print_hextable(FILE * in, FILE * out, unsigned char ASCII[], const rsize_t FILE_SIZE)
{
rsize_t i = 0;
rsize_t u = 0;
unsigned long fpos = 0;
rsize_t j = 0; //need this to create printable ASCII in output
unsigned char c = 0;
while ( i < FILE_SIZE )
{
c = fgetc(in);
colorchar(c);
#if 0
This printf actually forces printing of ASCII.
#endif
if ( i == 0 )
{ fprintf(out,"%08x:%c",i,0x20); }
else if ( (i%NUM_HEX_ROWS) == 0 )
{
fputc(0x20,out);
fputc(0x20,out);
if ( i >= NUM_HEX_ROWS )
{
fseek(in,-NUM_HEX_ROWS-1,SEEK_CUR);
}
else
{
fseek(in,0,SEEK_SET);
}
u = 0;
while (
u < NUM_HEX_ROWS
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
c = fgetc(in); //catch up to latest row
colorchar(c);
fprintf(out,"\n%08x:%c",i,0x20);
resetcolor();
}
colorchar(c);
(i%1 != 0) ? ( fprintf(out,"%02x",c) ) : ( fprintf(out,"%c%02x",0x20,c) );
i++;
resetcolor();
// Bug: Write code to place ff and extra spaces to align last ASCII line here
}
if ( i == FILE_SIZE )
{
rsize_t index = i;
while ( index % NUM_HEX_ROWS != 0 )
{
(index%2 == 0)
?
( fprintf(out,"%c%c%c",0x20,0x20,0x20) )
:
( fprintf(out,"%c%c%c",0x20,0x20,0x20) );
index++;
}
#if 0
This while loop is meant for
a line that is equal to
NUM_HEX_ROWS
#endif
if ( index % NUM_HEX_ROWS == 0 )
{
fputc(0x20,out);
fputc(0x20,out);
}
}
if ( i == FILE_SIZE && (i%NUM_HEX_ROWS) != 0 )
{
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(i%NUM_HEX_ROWS),SEEK_CUR);
u = 0;
while (
u < ( i%NUM_HEX_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
else // ( i == FILE_SIZE && (i%NUM_HEX_ROWS) == 0 )
{
rsize_t space_align = i;
fpos = ftell(in);
fseek(in,-(NUM_HEX_ROWS),SEEK_CUR);
u = 0;
while (
u < ( NUM_HEX_ROWS )
)
{
( c = fgetc(in) );
colorchar(c);
if ( isprint(c) )
{
fputc(c,out);
}
else
{
fprintf(out,"\u00b7");
}
u++;
resetcolor();
}
fseek(in,fpos,SEEK_SET);
}
}
#if 0
Last argument, argument index
argc-1, must have filename
#endif
int main(int argc, char ** argv)
{
FILE * in = NULL;
FILE * out = stdout;
if ( argc < 2 )
{
fprintf(in,"%llu: Less than two arguments!\n",__LINE__);
return 1;
}
if ( ( (argc-2) > 0 ) && ( ( in = fopen(argv[argc-2],"rb") ) != NULL ) )
{
if ( ( out = fopen(argv[argc-1],"wb+") ) == NULL )
{
fprintf(stderr,"\033[1;31m\n\0");
fprintf(stdout,"%llu: Failed to write to file %s!\n",__LINE__,argv[argc-1]);
fprintf(stderr,"\033[0m\n\0");
return 1;
}
}
else if ( ( in = fopen(argv[argc-1],"rb") ) == NULL )
{
fprintf(stderr,"\033[1;31m\n\0");
fprintf(stdout,"%llu: Failed to open file!\n",__LINE__);
fprintf(stderr,"\033[0m\n\0");
return 1;
}
fseek(in,0L,SEEK_END);
const rsize_t SIZE = ftell(in);
static unsigned char * ascii_line;
ascii_line = (unsigned char *)calloc(NUM_HEX_ROWS+1,sizeof(unsigned char));
rewind(in);
while ( *++argv != NULL && **argv == 0x2d )
{
switch ( *++(*argv) )
{
case 0x63:
{
// get column number
char const * column_num = *++argv;
while ( isdigit( *(*argv) ) != 0 )
{ (*argv)++; }
if ( **argv != 0x0 )
{
fprintf(stderr,"\033[1;31m\n\0");
fprintf(stderr,"%llu: Error! Column"
" argument is not a"
" type of unsigned"
" integer!\n",
__LINE__
);
fprintf(stderr,"\033[0m\n\0");
return 1;
}
NUM_HEX_ROWS = (rsize_t)strtol(column_num,NULL,10);
free(ascii_line);
ascii_line = (unsigned char *)calloc(NUM_HEX_ROWS,sizeof(unsigned char));
NUM_BIN_ROWS = (rsize_t)strtol(column_num,NULL,10);
NUM_OCT_ROWS = (rsize_t)strtol(column_num,NULL,10);
NUM_DEC_ROWS = (rsize_t)strtol(column_num,NULL,10);
break;
}
case 0x62:
{
bintable_request = 1;
free(ascii_line);
ascii_line = (unsigned char *)calloc(NUM_BIN_ROWS+1,sizeof(unsigned char));
break;
}
case 0x64:
{
dectable_request = 1;
free(ascii_line);
ascii_line = (unsigned char *)calloc(NUM_DEC_ROWS+1,sizeof(unsigned char));
break;
}
case 0x6f:
{
octtable_request = 1;
free(ascii_line);
ascii_line = (unsigned char *)calloc(NUM_OCT_ROWS+1,sizeof(unsigned char));
break;
}
case 0x70:
{
printview(in,out,SIZE);
return 0;
}
default:
{
break;
}
}
}
if ( dectable_request == 1 )
{
print_dectable(in,out,ascii_line,SIZE);
}
else if ( octtable_request == 1 )
{
print_octtable(in,out,ascii_line,SIZE);
}
else if ( bintable_request == 1 )
{
print_bintable2(in,out,ascii_line,SIZE);
}
else
{
print_hextable(in,out,ascii_line,SIZE);
}
if ( fclose(in) == EOF )
{
fprintf(stderr,"\033[1;31m\n\0");
fprintf(stderr,"%llu: Error! Failed to close %s\n",__LINE__,argv[argc-1]);
fprintf(stderr,"\033[0m\n\0");
return 1;
}
if ( fclose(out) == EOF )
{
fprintf(stderr,"\033[1;31m\n\0");
fprintf(stderr,"%llu: Error! Failed to close %s\n",__LINE__,argv[argc-1]);
fprintf(stderr,"\033[0m\n\0");
return 1;
}
return 0;
}
SHA256SUM: 592e94e830a99919e89f76e313513e5d87aee948c8bc7a324ef834c51e634e60 *tscd6.c