An article explaining how to independently verify that your IPSec
configuration is working.
This commit is contained in:
parent
2ee393d1be
commit
3a76b7c251
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=7457
4 changed files with 626 additions and 0 deletions
16
en_US.ISO8859-1/articles/ipsec-must/Makefile
Normal file
16
en_US.ISO8859-1/articles/ipsec-must/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
|||
# $FreeBSD$
|
||||
|
||||
DOC?= article
|
||||
|
||||
DOCFORMAT= html
|
||||
|
||||
FORMATS?= html
|
||||
|
||||
INSTALL_COMPRESSED?=gz
|
||||
INSTALL_ONLY_COMPRESSED?=
|
||||
|
||||
SRCS= article.sgml
|
||||
|
||||
DOC_PREFIX?= ${.CURDIR}/../../..
|
||||
|
||||
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
|
297
en_US.ISO8859-1/articles/ipsec-must/article.sgml
Normal file
297
en_US.ISO8859-1/articles/ipsec-must/article.sgml
Normal file
|
@ -0,0 +1,297 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Independent Verification of IPSec Functionality in FreeBSD</title>
|
||||
</head>
|
||||
|
||||
<body text="#000000" bgcolor="#FFFFFF">
|
||||
|
||||
<h1>Independent Verification of IPsec Functionality Under FreeBSD 3.0</h1>
|
||||
|
||||
<p align="center"><i>You installed IPsec and it seems to be working.
|
||||
How do you know? I describe a method for experimentally verifying
|
||||
that IPsec is working</i></p>
|
||||
|
||||
<h2>The Problem</h2>
|
||||
|
||||
<p>First, let's assume you have <a href="#Installing IPsec">installed
|
||||
<i>IPsec</i></a>. How do you know its <a href="#Caveat">working</a>?
|
||||
Sure, your connection won't work if its misconfigured, and it will work
|
||||
when you finally get it right. <i>Netstat</i> will list it. But can you
|
||||
independently confirm it?</p>
|
||||
|
||||
<h2>The Solution</h2>
|
||||
|
||||
<p>First, some crypto-relevent info theory:</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<p>Encrypted data is uniformly distributed, ie, has maximal entropy
|
||||
per symbol.</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>Raw, uncompressed data is typically redundant, i.e., has
|
||||
sub-maximal entropy.</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>Suppose you could measure the entropy of the data to- and from- your
|
||||
network interface. Then you could see the difference between unencrypted
|
||||
data and encrypted data. This would be true even if some of the data
|
||||
in "encrypted mode" was not encrypted ---as the outermost IP header must
|
||||
be, if the packet is to be routable.</p>
|
||||
|
||||
<h4><a name="MUST"></a>MUST</h4>
|
||||
|
||||
<p>Ueli Maurer's "Universal Statistical Test for Random Bit Generators"
|
||||
("MUST") quickly measures the entropy of a sample. It uses a
|
||||
compression-like algorithm. <a href="#Maurer's Universal Statistical
|
||||
Test">The code is given below for a variant which measures successive
|
||||
(~quarter megabyte) chunks of a file</a>.</p>
|
||||
|
||||
<h4><a NAME="Tcpdump"></a>Tcpdump</h4>
|
||||
|
||||
<p>We also need a way to capture the raw network data. A program called
|
||||
"<i>tcpdump</i>" lets you do this, if you have enabled the <i>Berkeley
|
||||
Packet Filter</i> interface in your <a
|
||||
href="#usr/src/sys/i386/conf/KERNELNAME">kernel's config file</a>.</p>
|
||||
|
||||
<p>The command</p>
|
||||
|
||||
<blockquote><b>tcpdump</b> <b>-c</b> 4000 <b>-s</b> 10000 <b>-w</b>
|
||||
<i>dumpfile.bin</i></blockquote>
|
||||
|
||||
<p>will capture 4000 raw packets to <i>dumpfile.bin</i>. Up to 10,000
|
||||
bytes per packet will be captured in this example.</p>
|
||||
|
||||
<h2>The Experiment</h2>
|
||||
|
||||
<p>Here's the experiment. Open a window to an IPsec host and another
|
||||
window to an insecure host.</p>
|
||||
|
||||
<p>Now start <a href="#Tcpdump">capturing packets</a>.</p>
|
||||
|
||||
<p>In the "secure" window, run the unix command "yes", which will stream
|
||||
the "y" character. After a while, stop this. Switch to the insecure
|
||||
window, and repeat. After a while, stop.</p>
|
||||
|
||||
<p>Now run <a href="#Maurer's Universal Statistical Test">MUST</a> on the
|
||||
captured packets. You should see something like the the following.
|
||||
The important thing to note is that the secure connection has 93% (6.7)
|
||||
of the expected value (7.18), and the "normal" connection has 29% (2.1)
|
||||
of the expected value.</p>
|
||||
|
||||
|
||||
<pre>% tcpdump -c 4000 -s 10000 -w ipsecdemo.bin
|
||||
% uliscan ipsecdemo.bin
|
||||
|
||||
Uliscan 21 Dec 98
|
||||
L=8 256 258560
|
||||
Measuring file ipsecdemo.bin
|
||||
Init done
|
||||
Expected value for L=8 is 7.1836656
|
||||
6.9396 --------------------------------------------------------
|
||||
6.6177 -----------------------------------------------------
|
||||
6.4100 ---------------------------------------------------
|
||||
2.1101 -----------------
|
||||
2.0838 -----------------
|
||||
2.0983 -----------------</pre>
|
||||
|
||||
<h2><a NAME="Caveat"></a>Caveat</h2>
|
||||
|
||||
<p>This experiment shows that IPsec <i>does</i> seem to be distributing the
|
||||
payload data <i>uniformly</i>, as encryption should. However, the
|
||||
experiment described here <i>can not </i>detect many possible flaws in a
|
||||
system (none of which do I have any evidence for). These include poor
|
||||
key generation or exchange, data or keys being visible to others, use of
|
||||
weak algorithms, kernel subversion, etc. Study the source; know the
|
||||
code.</p>
|
||||
|
||||
<h2><a NAME="IPsec"></a>IPsec -Definition</h2>
|
||||
|
||||
<p>Internet Protocol security extensions to IP v 4; required for IP v6. A
|
||||
protocol for negotiating encryption and authentication at the IP
|
||||
(host-to-host) level. SSL secures only one application socket; SSH
|
||||
secures only a login; PGP secures only a specified file or
|
||||
message. IPsec encrypts everything between two hosts.</p>
|
||||
|
||||
<h2><a NAME="Installing IPsec"></a>Installing IPsec</h2>
|
||||
|
||||
<p>Starting from the BSD 3.0 stable release,</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<p>install IPsec v0.04, rebuild, reinstall</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>run the administration tools (e.g, <i>ipsecadm</i>) and distribute
|
||||
keys (or use <i>Photuris</i> for key exchange)</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>set the routes (<i>rt</i>) up appropriately</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>You may want to make an "ipsec_setup" script containing the
|
||||
<i>ipsecadm</i> and <i>rt</i> commands which establish your IPsec
|
||||
tunnel. You can run this script automatically at boottime from your
|
||||
<i>/etc/rc.local</i> The ipsec_setup script will have to contain at
|
||||
least two <i>ipsecadm</i> commands and one <i>rt</i> command to be
|
||||
useful.</p>
|
||||
|
||||
<h2><a NAME="KERNELNAME"></a>usr/src/sys/i386/conf/KERNELNAME</h2>
|
||||
|
||||
<p>This needs to be present in the kernel config file in order to run
|
||||
IPsec. After adding it, run <i>config</i>, etc. and rebuild and
|
||||
reinstall.</p>
|
||||
|
||||
<pre># The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be
|
||||
# aware of the legal and administrative consequences of enabling this
|
||||
# option. Heh heh. The number of devices determines the maximum number of
|
||||
# simultaneous BPF clients programs runnable.
|
||||
pseudo-device bpfilter 2 #Berkeley packet filter
|
||||
|
||||
# IPSEC
|
||||
options IPSEC
|
||||
options "MD5"
|
||||
pseudo-device enc 1</pre>
|
||||
|
||||
<h2><a name="must"></a>Maurer's Universal Statistical Test (for block
|
||||
size=8 bits)</h2>
|
||||
|
||||
<pre><![ CDATA [/*
|
||||
ULISCAN.c ---blocksize of 8
|
||||
|
||||
1 Oct 98
|
||||
1 Dec 98
|
||||
21 Dec 98 uliscan.c derived from ueli8.c
|
||||
|
||||
This version has // comments removed for Sun cc
|
||||
|
||||
This implements Ueli M Maurer's "Universal Statistical Test for Random
|
||||
Bit Generators" using L=8
|
||||
|
||||
Accepts a filename on the command line; writes its results, with other
|
||||
info, to stdout.
|
||||
|
||||
Handles input file exhaustion gracefully.
|
||||
|
||||
Ref: J. Cryptology v 5 no 2, 1992 pp 89-105
|
||||
also on the web somewhere, which is where I found it.
|
||||
|
||||
-David Honig
|
||||
honig@sprynet.com
|
||||
|
||||
Usage:
|
||||
ULISCAN filename
|
||||
outputs to stdout
|
||||
*/
|
||||
|
||||
#define L 8
|
||||
#define V (1<<L)
|
||||
#define Q (10*V)
|
||||
#define K (100 *Q)
|
||||
#define MAXSAMP (Q + K)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
FILE *fptr;
|
||||
int i,j;
|
||||
int b, c;
|
||||
int table[V];
|
||||
double sum = 0.0;
|
||||
int iproduct = 1;
|
||||
int run;
|
||||
|
||||
extern double log(/* double x */);
|
||||
|
||||
printf("Uliscan 21 Dec 98 \nL=%d %d %d \n", L, V, MAXSAMP);
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: Uliscan filename\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Measuring file %s\n", argv[1]);
|
||||
}
|
||||
|
||||
fptr = fopen(argv[1],"rb");
|
||||
|
||||
if (fptr == NULL) {
|
||||
printf("Can't find %s\n", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (i = 0; i < V; i++) {
|
||||
table[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < Q; i++) {
|
||||
b = fgetc(fptr);
|
||||
table[b] = i;
|
||||
}
|
||||
|
||||
printf("Init done\n");
|
||||
|
||||
printf("Expected value for L=8 is 7.1836656\n");
|
||||
|
||||
run = 1;
|
||||
|
||||
while (run) {
|
||||
sum = 0.0;
|
||||
iproduct = 1;
|
||||
|
||||
if (run)
|
||||
for (i = Q; run && i < Q + K; i++) {
|
||||
j = i;
|
||||
b = fgetc(fptr);
|
||||
|
||||
if (b < 0)
|
||||
run = 0;
|
||||
|
||||
if (run) {
|
||||
if (table[b] > j)
|
||||
j += K;
|
||||
|
||||
sum += log((double)(j-table[b]));
|
||||
|
||||
table[b] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!run)
|
||||
printf("Premature end of file; read %d blocks.\n", i - Q);
|
||||
|
||||
sum = (sum/((double)(i - Q))) / log(2.0);
|
||||
printf("%4.4f ", sum);
|
||||
|
||||
for (i = 0; i < (int)(sum*8.0 + 0.50); i++)
|
||||
printf("-");
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* refill initial table */
|
||||
if (0) {
|
||||
for (i = 0; i < Q; i++) {
|
||||
b = fgetc(fptr);
|
||||
if (b < 0) {
|
||||
run = 0;
|
||||
} else {
|
||||
table[b] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]]></pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
16
en_US.ISO_8859-1/articles/ipsec-must/Makefile
Normal file
16
en_US.ISO_8859-1/articles/ipsec-must/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
|||
# $FreeBSD$
|
||||
|
||||
DOC?= article
|
||||
|
||||
DOCFORMAT= html
|
||||
|
||||
FORMATS?= html
|
||||
|
||||
INSTALL_COMPRESSED?=gz
|
||||
INSTALL_ONLY_COMPRESSED?=
|
||||
|
||||
SRCS= article.sgml
|
||||
|
||||
DOC_PREFIX?= ${.CURDIR}/../../..
|
||||
|
||||
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
|
297
en_US.ISO_8859-1/articles/ipsec-must/article.sgml
Normal file
297
en_US.ISO_8859-1/articles/ipsec-must/article.sgml
Normal file
|
@ -0,0 +1,297 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Independent Verification of IPSec Functionality in FreeBSD</title>
|
||||
</head>
|
||||
|
||||
<body text="#000000" bgcolor="#FFFFFF">
|
||||
|
||||
<h1>Independent Verification of IPsec Functionality Under FreeBSD 3.0</h1>
|
||||
|
||||
<p align="center"><i>You installed IPsec and it seems to be working.
|
||||
How do you know? I describe a method for experimentally verifying
|
||||
that IPsec is working</i></p>
|
||||
|
||||
<h2>The Problem</h2>
|
||||
|
||||
<p>First, let's assume you have <a href="#Installing IPsec">installed
|
||||
<i>IPsec</i></a>. How do you know its <a href="#Caveat">working</a>?
|
||||
Sure, your connection won't work if its misconfigured, and it will work
|
||||
when you finally get it right. <i>Netstat</i> will list it. But can you
|
||||
independently confirm it?</p>
|
||||
|
||||
<h2>The Solution</h2>
|
||||
|
||||
<p>First, some crypto-relevent info theory:</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<p>Encrypted data is uniformly distributed, ie, has maximal entropy
|
||||
per symbol.</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>Raw, uncompressed data is typically redundant, i.e., has
|
||||
sub-maximal entropy.</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>Suppose you could measure the entropy of the data to- and from- your
|
||||
network interface. Then you could see the difference between unencrypted
|
||||
data and encrypted data. This would be true even if some of the data
|
||||
in "encrypted mode" was not encrypted ---as the outermost IP header must
|
||||
be, if the packet is to be routable.</p>
|
||||
|
||||
<h4><a name="MUST"></a>MUST</h4>
|
||||
|
||||
<p>Ueli Maurer's "Universal Statistical Test for Random Bit Generators"
|
||||
("MUST") quickly measures the entropy of a sample. It uses a
|
||||
compression-like algorithm. <a href="#Maurer's Universal Statistical
|
||||
Test">The code is given below for a variant which measures successive
|
||||
(~quarter megabyte) chunks of a file</a>.</p>
|
||||
|
||||
<h4><a NAME="Tcpdump"></a>Tcpdump</h4>
|
||||
|
||||
<p>We also need a way to capture the raw network data. A program called
|
||||
"<i>tcpdump</i>" lets you do this, if you have enabled the <i>Berkeley
|
||||
Packet Filter</i> interface in your <a
|
||||
href="#usr/src/sys/i386/conf/KERNELNAME">kernel's config file</a>.</p>
|
||||
|
||||
<p>The command</p>
|
||||
|
||||
<blockquote><b>tcpdump</b> <b>-c</b> 4000 <b>-s</b> 10000 <b>-w</b>
|
||||
<i>dumpfile.bin</i></blockquote>
|
||||
|
||||
<p>will capture 4000 raw packets to <i>dumpfile.bin</i>. Up to 10,000
|
||||
bytes per packet will be captured in this example.</p>
|
||||
|
||||
<h2>The Experiment</h2>
|
||||
|
||||
<p>Here's the experiment. Open a window to an IPsec host and another
|
||||
window to an insecure host.</p>
|
||||
|
||||
<p>Now start <a href="#Tcpdump">capturing packets</a>.</p>
|
||||
|
||||
<p>In the "secure" window, run the unix command "yes", which will stream
|
||||
the "y" character. After a while, stop this. Switch to the insecure
|
||||
window, and repeat. After a while, stop.</p>
|
||||
|
||||
<p>Now run <a href="#Maurer's Universal Statistical Test">MUST</a> on the
|
||||
captured packets. You should see something like the the following.
|
||||
The important thing to note is that the secure connection has 93% (6.7)
|
||||
of the expected value (7.18), and the "normal" connection has 29% (2.1)
|
||||
of the expected value.</p>
|
||||
|
||||
|
||||
<pre>% tcpdump -c 4000 -s 10000 -w ipsecdemo.bin
|
||||
% uliscan ipsecdemo.bin
|
||||
|
||||
Uliscan 21 Dec 98
|
||||
L=8 256 258560
|
||||
Measuring file ipsecdemo.bin
|
||||
Init done
|
||||
Expected value for L=8 is 7.1836656
|
||||
6.9396 --------------------------------------------------------
|
||||
6.6177 -----------------------------------------------------
|
||||
6.4100 ---------------------------------------------------
|
||||
2.1101 -----------------
|
||||
2.0838 -----------------
|
||||
2.0983 -----------------</pre>
|
||||
|
||||
<h2><a NAME="Caveat"></a>Caveat</h2>
|
||||
|
||||
<p>This experiment shows that IPsec <i>does</i> seem to be distributing the
|
||||
payload data <i>uniformly</i>, as encryption should. However, the
|
||||
experiment described here <i>can not </i>detect many possible flaws in a
|
||||
system (none of which do I have any evidence for). These include poor
|
||||
key generation or exchange, data or keys being visible to others, use of
|
||||
weak algorithms, kernel subversion, etc. Study the source; know the
|
||||
code.</p>
|
||||
|
||||
<h2><a NAME="IPsec"></a>IPsec -Definition</h2>
|
||||
|
||||
<p>Internet Protocol security extensions to IP v 4; required for IP v6. A
|
||||
protocol for negotiating encryption and authentication at the IP
|
||||
(host-to-host) level. SSL secures only one application socket; SSH
|
||||
secures only a login; PGP secures only a specified file or
|
||||
message. IPsec encrypts everything between two hosts.</p>
|
||||
|
||||
<h2><a NAME="Installing IPsec"></a>Installing IPsec</h2>
|
||||
|
||||
<p>Starting from the BSD 3.0 stable release,</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<p>install IPsec v0.04, rebuild, reinstall</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>run the administration tools (e.g, <i>ipsecadm</i>) and distribute
|
||||
keys (or use <i>Photuris</i> for key exchange)</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>set the routes (<i>rt</i>) up appropriately</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>You may want to make an "ipsec_setup" script containing the
|
||||
<i>ipsecadm</i> and <i>rt</i> commands which establish your IPsec
|
||||
tunnel. You can run this script automatically at boottime from your
|
||||
<i>/etc/rc.local</i> The ipsec_setup script will have to contain at
|
||||
least two <i>ipsecadm</i> commands and one <i>rt</i> command to be
|
||||
useful.</p>
|
||||
|
||||
<h2><a NAME="KERNELNAME"></a>usr/src/sys/i386/conf/KERNELNAME</h2>
|
||||
|
||||
<p>This needs to be present in the kernel config file in order to run
|
||||
IPsec. After adding it, run <i>config</i>, etc. and rebuild and
|
||||
reinstall.</p>
|
||||
|
||||
<pre># The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be
|
||||
# aware of the legal and administrative consequences of enabling this
|
||||
# option. Heh heh. The number of devices determines the maximum number of
|
||||
# simultaneous BPF clients programs runnable.
|
||||
pseudo-device bpfilter 2 #Berkeley packet filter
|
||||
|
||||
# IPSEC
|
||||
options IPSEC
|
||||
options "MD5"
|
||||
pseudo-device enc 1</pre>
|
||||
|
||||
<h2><a name="must"></a>Maurer's Universal Statistical Test (for block
|
||||
size=8 bits)</h2>
|
||||
|
||||
<pre><![ CDATA [/*
|
||||
ULISCAN.c ---blocksize of 8
|
||||
|
||||
1 Oct 98
|
||||
1 Dec 98
|
||||
21 Dec 98 uliscan.c derived from ueli8.c
|
||||
|
||||
This version has // comments removed for Sun cc
|
||||
|
||||
This implements Ueli M Maurer's "Universal Statistical Test for Random
|
||||
Bit Generators" using L=8
|
||||
|
||||
Accepts a filename on the command line; writes its results, with other
|
||||
info, to stdout.
|
||||
|
||||
Handles input file exhaustion gracefully.
|
||||
|
||||
Ref: J. Cryptology v 5 no 2, 1992 pp 89-105
|
||||
also on the web somewhere, which is where I found it.
|
||||
|
||||
-David Honig
|
||||
honig@sprynet.com
|
||||
|
||||
Usage:
|
||||
ULISCAN filename
|
||||
outputs to stdout
|
||||
*/
|
||||
|
||||
#define L 8
|
||||
#define V (1<<L)
|
||||
#define Q (10*V)
|
||||
#define K (100 *Q)
|
||||
#define MAXSAMP (Q + K)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
FILE *fptr;
|
||||
int i,j;
|
||||
int b, c;
|
||||
int table[V];
|
||||
double sum = 0.0;
|
||||
int iproduct = 1;
|
||||
int run;
|
||||
|
||||
extern double log(/* double x */);
|
||||
|
||||
printf("Uliscan 21 Dec 98 \nL=%d %d %d \n", L, V, MAXSAMP);
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: Uliscan filename\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Measuring file %s\n", argv[1]);
|
||||
}
|
||||
|
||||
fptr = fopen(argv[1],"rb");
|
||||
|
||||
if (fptr == NULL) {
|
||||
printf("Can't find %s\n", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (i = 0; i < V; i++) {
|
||||
table[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < Q; i++) {
|
||||
b = fgetc(fptr);
|
||||
table[b] = i;
|
||||
}
|
||||
|
||||
printf("Init done\n");
|
||||
|
||||
printf("Expected value for L=8 is 7.1836656\n");
|
||||
|
||||
run = 1;
|
||||
|
||||
while (run) {
|
||||
sum = 0.0;
|
||||
iproduct = 1;
|
||||
|
||||
if (run)
|
||||
for (i = Q; run && i < Q + K; i++) {
|
||||
j = i;
|
||||
b = fgetc(fptr);
|
||||
|
||||
if (b < 0)
|
||||
run = 0;
|
||||
|
||||
if (run) {
|
||||
if (table[b] > j)
|
||||
j += K;
|
||||
|
||||
sum += log((double)(j-table[b]));
|
||||
|
||||
table[b] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!run)
|
||||
printf("Premature end of file; read %d blocks.\n", i - Q);
|
||||
|
||||
sum = (sum/((double)(i - Q))) / log(2.0);
|
||||
printf("%4.4f ", sum);
|
||||
|
||||
for (i = 0; i < (int)(sum*8.0 + 0.50); i++)
|
||||
printf("-");
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* refill initial table */
|
||||
if (0) {
|
||||
for (i = 0; i < Q; i++) {
|
||||
b = fgetc(fptr);
|
||||
if (b < 0) {
|
||||
run = 0;
|
||||
} else {
|
||||
table[b] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]]></pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
Loading…
Reference in a new issue