📄 rfc1505.txt
字号:
#define STRTL 0
#define STEPL 1
#define STOPL 7
static FILE *in;
static FILE *out;
static int getbuf;
static int getlen;
static long in_count;
static long out_count;
static long crc;
static long crctable[256];
static uchar xxcodes[] =
"+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz";
static uchar ddcodes[256];
static uchar text[N];
#define CRCPOLY 0xEDB88320
#define CRC_MASK 0xFFFFFFFF
#define UPDATE_CRC(crc, c) \
crc = crctable[((uchar)(crc) ^ (uchar)(c)) & 0xFF] \
^ (crc >> 8)
#define START_RECD "* LZJU90"
void MakeCrctable() /* Initialize CRC-32 table */
{
uint i, j;
long r;
for (i = 0; i <= 255; i++) {
r = i;
for (j = 8; j > 0; j--) {
if (r & 1)
r = (r >> 1) ^ CRCPOLY;
else
Costanzo, Robinson & Ullmann [Page 22]
RFC 1505 Encoding Header Field August 1993
r >>= 1;
}
crctable[i] = r;
}
}
int GetXX() /* Get xxcode and translate */
{
int c;
do {
if ((c = fgetc(in)) == EOF)
c = 0;
} while (c == '\n');
in_count++;
return ddcodes[c];
}
int GetBit() /* Get one bit from input buffer */
{
int c;
while (getlen <= 0) {
c = GetXX();
getbuf |= c << (10-getlen);
getlen += 6;
}
c = (getbuf & 0x8000) != 0;
getbuf <<= 1;
getbuf &= 0xFFFF;
getlen--;
return(c);
}
int GetBits(int len) /* Get len bits */
{
int c;
while (getlen <= 10) {
c = GetXX();
getbuf |= c << (10-getlen);
getlen += 6;
}
if (getlen < len) {
c = (uint)getbuf >> (16-len);
Costanzo, Robinson & Ullmann [Page 23]
RFC 1505 Encoding Header Field August 1993
getbuf = GetXX();
c |= getbuf >> (6+getlen-len);
getbuf <<= (10+len-getlen);
getbuf &= 0xFFFF;
getlen -= len - 6;
}
else {
c = (uint)getbuf >> (16-len);
getbuf <<= len;
getbuf &= 0xFFFF;
getlen -= len;
}
return(c);
}
int DecodePosition() /* Decode offset position pointer */
{
int c;
int width;
int plus;
int pwr;
plus = 0;
pwr = 1 << STRTP;
for (width = STRTP; width < STOPP; width += STEPP) {
c = GetBit();
if (c == 0)
break;
plus += pwr;
pwr <<= 1;
}
if (width != 0)
c = GetBits(width);
c += plus;
return(c);
}
int DecodeLength() /* Decode code length */
{
int c;
int width;
int plus;
int pwr;
plus = 0;
pwr = 1 << STRTL;
Costanzo, Robinson & Ullmann [Page 24]
RFC 1505 Encoding Header Field August 1993
for (width = STRTL; width < STOPL; width += STEPL) {
c = GetBit();
if (c == 0)
break;
plus += pwr;
pwr <<= 1;
}
if (width != 0)
c = GetBits(width);
c += plus;
return(c);
}
void InitCodes() /* Initialize decode table */
{
int i;
for (i = 0; i < 256; i++) ddcodes[i] = 0;
for (i = 0; i < 64; i++) ddcodes[xxcodes[i]] = i;
return;
}
main(int ac, char **av) /* main program */
{
int r;
int j, k;
int c;
int pos;
char buf[80];
char name[3];
long num, bytes;
if (ac < 3) {
fprintf(stderr, "usage: judecode in out\n");
return(1);
}
in = fopen(av[1], "r");
if (!in){
fprintf(stderr, "Can't open %s\n", av[1]);
return(1);
}
out = fopen(av[2], "wb");
if (!out) {
fprintf(stderr, "Can't open %s\n", av[2]);
fclose(in);
Costanzo, Robinson & Ullmann [Page 25]
RFC 1505 Encoding Header Field August 1993
return(1);
}
while (1) {
if (fgets(buf, sizeof(buf), in) == NULL) {
fprintf(stderr, "Unexpected EOF\n");
return(1);
}
if (strncmp(buf, START_RECD, strlen(START_RECD)) == 0)
break;
}
in_count = 0;
out_count = 0;
getbuf = 0;
getlen = 0;
InitCodes();
MakeCrctable();
crc = CRC_MASK;
r = 0;
while (feof(in) == 0) {
c = DecodeLength();
if (c == 0) {
c = GetBits(8);
UPDATE_CRC(crc, c);
out_count++;
text[r] = c;
fputc(c, out);
if (++r >= N)
r = 0;
}
else {
pos = DecodePosition();
if (pos == 0)
break;
pos--;
j = c + THRESHOLD - 1;
pos = r - pos - 1;
if (pos < 0)
pos += N;
for (k = 0; k < j; k++) {
c = text[pos];
text[r] = c;
UPDATE_CRC(crc, c);
Costanzo, Robinson & Ullmann [Page 26]
RFC 1505 Encoding Header Field August 1993
out_count++;
fputc(c, out);
if (++r >= N)
r = 0;
if (++pos >= N)
pos = 0;
}
}
}
fgetc(in); /* skip newline */
if (fscanf(in, "* %ld %lX", &bytes, &num) != 2) {
fprintf(stderr, "CRC record not found\n");
return(1);
}
else if (crc != num) {
fprintf(stderr,
"CRC error, expected %lX, found %lX\n",
crc, num);
return(1);
}
else if (bytes != out_count) {
fprintf(stderr,
"File size error, expected %lu, found %lu\n",
bytes, out_count);
return(1);
}
else
fprintf(stderr,
"File decoded to %lu bytes correctly\n",
out_count);
fclose(in);
fclose(out);
return(0);
}
5.3.1 An example of an Encoder
Many algorithms are possible for the encoder, with different
tradeoffs between speed, size, and complexity. The following is a
simple example program which is fairly efficient; more sophisticated
implementations will run much faster, and in some cases produce
Costanzo, Robinson & Ullmann [Page 27]
RFC 1505 Encoding Header Field August 1993
somewhat better compression.
This example also shows that the encoder need not use the entire
window available. Not using the full window costs a small amount of
compression, but can greatly increase the speed of some algorithms.
/* LZJU 90 Encoding program */
/* Written By Robert Jung and Robert Ullmann, 1990 and 1991. */
/* This code is NOT COPYRIGHT, not protected. It is in the true
Public Domain. */
#include <stdio.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define N 24000 /* Size of window buffer */
#define F 256 /* Size of look-ahead buffer */
#define THRESHOLD 3
#define K 16384 /* Size of hash table */
#define STRTP 9
#define STEPP 1
#define STOPP 14
#define STRTL 0
#define STEPL 1
#define STOPL 7
#define CHARSLINE 78
static FILE *in;
static FILE *out;
static int putlen;
static int putbuf;
static int char_ct;
static long in_count;
static long out_count;
static long crc;
static long crctable[256];
static uchar xxcodes[] =
"+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz";
uchar window_text[N + F + 1];
Costanzo, Robinson & Ullmann [Page 28]
RFC 1505 Encoding Header Field August 1993
/* text contains window, plus 1st F of window again
(for comparisons) */
uint hash_table[K];
/* table of pointers into the text */
#define CRCPOLY 0xEDB88320
#define CRC_MASK 0xFFFFFFFF
#define UPDATE_CRC(crc, c) \
crc = crctable[((uchar)(crc) ^ (uchar)(c)) & 0xFF] \
^ (crc >> 8)
void MakeCrctable() /* Initialize CRC-32 table */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -