1990年

#1792/1982 計算機と算法
★タイトル (SCIENCE )  90/ 1/29   5:55  ( 73)
デバッグお願い>新スライド辞書圧縮/奥村
★内容
 やっと乗ってきました。最初からスライド辞書部を書き直してみました。考えや
すくするために能率を犠牲にしてインサートノードからgotoを追い出したり処
理をサブルーチン化したりしましたのでその分遅くなっていますが、percol
ating updateは吉崎版よりずっと簡単になったので、実質的には若干
速くなったのではないかと思います。吉崎さんが指摘されたような同じ文字にとき
どき別の文字が入っている病理的なファイルでも試してみましたが良好なようです。
バグがないかチェックしてくださいませんか。
……略……
#1973/2051 計算機と算法
★タイトル (SCIENCE )  90/ 4/ 3  17:16  (162)
画像圧縮>これまでのまとめ/奥村
★内容
 まず目的ですが、CAI教材やゲームソフトの画面を十分高速に画面に表示する
ことです。簡単にベクトルデータとして表せるものはなるべくそのようにし、スキ
ャナから取り込んだ画像をおもに対象とします(写真、イラストなど)。考えます。
圧縮比が良くてもあまり復号の遅いものは駄目です。圧縮時間はかかってもかまい
ません(といっても限度がありますが)。とりあえずPC−9801用を考えます。
 産物は、なるべくANSI規格に従ったC、またはTurbo Pascalの
ソースコードの形とし、誰でも自分の目的に合うように改変して自分のプログラム
に組み込めるようにしたいのです。
 PC−9801では、グラフィックプレーンは古いVM2(私の使っているもの)
までは3枚、それ以後は4枚あり、それぞれ8色、16色の表示が可能です。
 各プレーンのグラフィックRAMの1バイトは横に並んだ8ドットを表します。
最初の1バイトは左上の8ドット、次の1バイトはその右の8ドット、……という
具合になっています。80バイトで640ドット、つまり横の線1本分になります。
横の線は400本ありますから、1プレーンは32000バイトになります。
 画像の情報をどのような形で見ていくかですが、点ごとに色コードを見ていく方
法と、色プレーンごとにあたかも単色のように考えて処理するかの、2通りが考え
られます。ここではプレーンの数を気にしなくてもいい後者の方法を考えることに
します。
 また、点ごとに見ていくか、1バイト分(横8個の点)をまとめて扱うかの、2
通りの方法があります。ここでは、なるべく高速に処理したいので、1バイト分を
まとめて扱うことにします。ただし、ビットごとの処理を十分高速にできるならば、
点ごとに見ていく方が圧縮比が良くなるかもしれません。このあたりはこれからの
課題です。
 バイトごとの処理の場合は、次のバイトは画面上では8ドット離れた領域を表し
ますが、80バイト目は画面上ではすぐ下の領域を表します。したがって、圧縮の
ためには、ビデオRAM上のバイトの順序を無視して、上下に見ていった方が圧縮
比が良くなると思われます。たとえば左上隅から始めて下へ下へと行き、左下隅ま
で行ったら右に1つ進み、また上に上がるというふうにジグザグに見ていくのがよ
いのではないかと思います。
 このようなバイトの並びをどうしたら圧縮できるかですが、画像の特質として、
第1段階の圧縮としては連長圧縮が向いているようです。つまり、同じバイトがい
くつ連続して続くかを調べ、それを数で表すのです。
 連長圧縮の原理を簡単に説明するために、画像でなくふつうのテキストを考えま
しょう。たとえばAAAABBCというテキストを4A2B1C(またはA4B2
C1)と表すのが連長圧縮です。ただしこれではABABは1A1B1A1Bとな
ってかえって長くなってしまいます。1個の場合は「1」を省略すればいいではな
いかと思われるかもしれませんが、数の1と文字コードの1は区別できないので、
そう簡単ではないのです。ただし余分に1ビットを使って数と文字を区別するとい
う手もあります。しかし1ビットという半端なものを混在させるとせっかくバイト
ごとになっている文字情報がバイトの境界をまたぐことになってしまいます。また、
性質の違う情報(文字・数)が混在すると、結果をさらに圧縮しようというときに、
圧縮しにくくなります。これを防ぐため、文字か数かを表すビットは別領域に置く
のが望ましいと考えられます。
 もっと簡単に数(連長)と文字とを区別する方法があります。エスケープ文字を
使う方法です。
 まずテキストを一通り調べて、なるべくあまり使われていない文字を1つ選び、
それをエスケープ文字と名づけます。たとえば¥という文字が少ないなら、¥をエ
スケープ文字とします。そして、数(連長)を表すには¥3とか¥5のように前に
エスケープ文字を冠します。エスケープ文字自体は¥0のように表します。この方
法ではAAAABBCは¥4ABBCと表します(BBは¥2Bとするとかえって
長くなるのでBBのままにします)。4連以上しか縮まないので、連の長さは3を
引いた値にすることができます(0は¥0に使いますからのけておきます)。この
方法では長さ258の連まで3バイトで表せます。また、たとえば¥255のとき
は次の2バイトで連長を表すようにすれば、たとえば全く使われていないプレーン
でも5バイトで表せます。実際には、どの文字をエスケープ文字にしたかを出力し
なければならないので、各プレーンあたり最小6バイト必要です。
 この方法は、比較的長い連が多い場合に効力を発揮しますが、3バイト以下の連
ばかりの場合は全く縮みません(しかし元より大きくはなりません)。
 また、タイルパターンのように、交互に別の文字が出てくる場合(テキストの例
でいえばABABABのようなパターン)も、縮みません。
 ABABABを縮めるためには次のような工夫も可能です。
 各バイトの文字コードを a,b,c,…… とします。連長圧縮をかける前処
理として、これを a,(a xor b),(b xor c),…… のよう
に直します。これだと、a=b=cの場合には a,0,0,…… となり、交互
に a,b,a,b,…… と並ぶ場合には a,(a xor b),
(a xor b),…… となり、いずれにしても、最初の1文字を除いて同じ
値になってしまいます。元に戻すには、a xor (a xor b) = b
を使えばよいのです
 しかし、この方法にも欠点はあります。それは、連長が1つ短くなってしまうこ
とです。このため、比較的短い連が多い場合には、圧縮比が悪くなります。それに、
ABCABCABCというパターンはうまくいきません。むしろ、このような同じ
パターンの連続は、圧縮を2段階にして、2段目の圧縮で処理するのが良いかもし
れません(後述)。
 3バイト以下の短い連が多い場合には、上述の方法では縮まないので、別の方法
を考えなければなりません。
 一つの方法は、連長を表すためのビット数を可変にすることです。
 たとえば
  1 …… 0    (1ビット)
  2 …… 10   (2ビット)
  3 …… 110  (3ビット)
  4 …… 1110 (4ビット)
というような数の表し方ができます。この場合にも、せっかくバイトの境界が揃っ
ているデータを崩したくないので、連長は別領域に格納するのがよいでしょう。た
とえばAAAABBCなら
  連長情報 1110100
  文字情報 ABC
となります。
 なお、この方法は、文字の変わり目をビット1で表す方法とじつは同値です。こ
の後者の方法では
  連長情報 1000101
  文字情報 ABC
となりますが、意味は同じことです。
 連長を表すビット数を可変にする方法はいろいろあります。たとえば
  1 …… 0    (1ビット)
  2 …… 10   (2ビット)
  3 …… 110  (3ビット)
  4 …… 11100 (5ビット)
  5 …… 11101 (5ビット)
  6 …… 11110 (5ビット)
  7 …… 1111100 (7ビット)
  8 …… 1111101 (7ビット)
  9 …… 1111110 (7ビット)
 10 …… 111111100 (9ビット)
とすれば、4を表すときはさきほどより1ビット長くなりますが、他の場合はすべ
て、さきほどと同じか、より短くなります。連長4が比較的多い場合にはこの方法
は向きませんが、そうでない場合にはこの方が短くなります。
 その他にも、可変長符号は無数に考えられます。
 どのような可変長符号が最適かは、その画像の連長の分布によります。最初に連
長の分布を調べて、その分布にとって最適な(最もよく縮まる)符号を作るアルゴ
リズムを何十年も前にハフマンという人が考えました。彼のアルゴリズムで作った
符号をハフマン符号といいます。しかしここではハフマン符号化まで考えないこと
にします。
 さて、これで第1段階の圧縮ができました。連長部分と文字(画素)部分とは別
に格納してあるとします。連長部分は、もしハフマン符号を用いたならそれ以上は
縮まないでしょうし、そうでなくても、うまく考えた可変長符号なら、ほぼ最適に
なっているでしょうから、これ以上縮めることは考えないことにします。
 文字(画素)情報の部分は、もっと縮むはずです。
 まず、文字の分布のことを考えましょう。256通りの文字のうち、頻繁に使わ
れるものもあれば、そうでないものもあるでしょう。これらをどれも8ビットで表
すのはもったいないことです。頻繁に現れるものほど少ないビット数で表す方が縮
まります。そこで、ここでも最適な可変長符号を見つけるハフマンの方法が使えそ
うです。しかし、本稿ではそこまで考えないことにします。
 ハフマン法のように分布に基づく方法以外によく使われる圧縮法としては、UN
IXのcompressコマンドで使われるLZW法(ARCやPKARCもこれ
にならっています)、LArcのLZSS法があります(LHarcはLZSS法
と動的ハフマン法を組み合わせています)。このうち、ここではLZSS法を解説
しましょう。
 たとえばABCABCABCというテキストがあったとします。このとき、最初
の3文字はそのまま出力します。次の6文字は、左に3つ戻ったところから始まる
6文字と全く同じですので、(3つ戻る、6文字)という情報を書き出すだけで十
分です。つまり、ABC(3,6)と符号化できます。この(位置、長さ)のペア
は、たとえば位置を8個前まで、長さを32文字までに制限すれば、8ビットで表
せます(長さ0や1はありえないので、実際には長さ34文字まで表せます)。8
個前とか32文字とかいう数はでたらめに言っただけで、実験してみて最適の組み
合わせを選ぶべきです。ただ、テキスト圧縮と違って、画像の場合には同じパター
ンが出てくるのはタイリングパターンのような場合が多いと考えられますので、あ
まり遠くまで調べなくてもよいという感じがします。長さは長いほどいいのですが、
あわせて8ビットにした方が処理が速くなると思います。
 この方法では、各バイト文字そのものであるか(位置、長さ)ペアであるかを区
別するためにさらに1ビット必要です。この1ビットも別領域にしまっておくのが
よいでしょう。性質の違うデータは別にするのが、あとでLHarcでさらに圧縮
するためにも、良いことだと思います。
 ちなみに、LHarcでは位置は約4千個前まで、長さは60文字まで調べてい
るので、能率を上げるため、2分木というデータ構造を使っています(第2版では
さらに進んだデータ構造を取り入れます)。しかし8バイト前まで調べるだけなら
通常の文字列サーチでも十分でしょう。
 圧縮法は、これ以外にもいろいろ考えられ、また、圧縮ファイルのフォーマット
も、いろいろ工夫できると思います。ちなみに、画像ファイルの標準としては
    TIFF (tagged image file format)
というのがあるそうですが、詳しいことは知りません。
 画像ローダを作られるなら、ヘッダの構造をよく練ることが大切です。違うフォ
ーマットのファイルを読んでしまったときに、間違いであることをできるだけ確実
にチェックできるようにしなければなりません。そのためには、最初の数バイトに
は何らかの署名を入れておきます。LHarcの場合は -lh0- とか -lh1-
というような圧縮方法を表す文字列を最初の5バイトとしています。これはLAr
c以来の伝統で、元を辿ればかの有名な Software Tools in Pascal の本にあるア
ーカイバが -h- というヘッダを使っています。
 圧縮法やヘッダの構造も進化するでしょうから、方法名は必ず入れるべきです。
逆にいえば、方法名さえヘッダに入れておけば、画像ローダを作る方は、とりあえ
ず適当な方法で作ってしまい、あとでゆっくり改良することができます。
 こういう具合に、いろいろ考えてみましたが、もう春休みは明日だけ。他に仕事
もあるので、プログラムを完成させる時間はなさそうです。
#1977/2051 計算機と算法
★タイトル (SCIENCE )  90/ 4/ 4   6:20  ( 18)
画像圧縮>もう一つ思いつきました/奥村
★内容
 エスケープ文字法よりこの方がいいかもしれません。前回と同様に、画面の横に
並んだ8ビット分を文字1個と考えて、あたかもテキスト圧縮のように説明します。
 たとえば
   PQRSTTTTUV
なら、
   PQRSTTTTUV
   ×××××○○○×× ← 直前と同じかどうか調べて
       5  3 2 ← その個数を数える
として、
   文字部分 PQRSTUV
   連長部分 5、3、2
とします。エスケープ文字法と同様に、長さ3以下の連はこの方法では縮みません。
しかし、エスケープ文字が不要であり、文字部分と連長部分を分けられるので、第
2段階の圧縮をする場合にも好都合です。さらに、連長部分を可変長符号で表す場
合にもこの方が好都合です。

 追伸:ROM男さん般若さんどうも。デコーダは上の方法でもし今日中にできれ
ば作ります。そんなに縮まるならどこかバグっているのかもしれません。

このころ,「計算機と算法」ボードの #2050 で,いよいよ SHIMA さん(大島先生)の dviout,dviprt が登場します。

さて,いよいよ私家版圧縮アーカイバ ar の登場です (当時は UNIX に ar という標準コマンドがあることを知りませんでした)。 ヘッダの2000年対応も完璧です。

#2053/3340 計算機と算法
★タイトル (SCIENCE )  90/ 4/23   6: 3  ( 16)
新圧縮アーカイバ/奥村
★内容
 また改良版を作ってみました。
 圧縮アルゴリズムは、符号語を16ビットに制限するところだけ違います。この
アルゴリズムはROM男さんの作られた正しいアルゴリズムではなく、ソースコー
ドをできるだけ小さくするような手抜きアルゴリズムです。手抜きといえば、四捨
五入アルゴリズムも村上さんが考えた正しいアルゴリズムではなく手抜きです。た
だしLHarcより少し桁あふれに注意を払っています。
 ヘッダは、今回はLHarcとの互換性を一切考慮せず、基本ヘッダはANSI
Cの枠内で得られる情報を過不足なく保存するにとどめ、OS依存情報はすべて拡
張ヘッダに譲りました。プログラム名は混乱を避けるためarに変更しました。
 ANSI Cでは最後に修正した日時を得ることができないので、書庫に入れた
日時だけ基本ヘッダに収めます。この日時は、ANSIではlocal(DST情
報なし)、local(DSTである)、local(DSTでない)、UTCの
4種類が可能なので、2ビット分のフラグをつけました。DOSは1980年から、
UNIXは1970年からの日時になっていますが、ANSIでは1900年から
可能になっているので、日時4バイトでは少なく、上記フラグも合わせて5バイト
にしました。これで5900A.D.頃まで使えます。

LHARC 改め LH 2.0 がまだ完成していないうちに偽物が現れ, 吉崎さんが激怒されます。 次のメッセージはダウンロードした際に行抜けが生じています。

#2070/3340 計算機と算法
★タイトル (SCIENCE )  90/ 4/26   6: 3  ( 37)
LH2.0の偽物出回る/奥村
★内容
 ついにpcsでLH2.0の偽物が出たそうです。
 (念のためにつけ加えれば、LH2.0は吉崎さんのLHarcの後継アーカイ
バで、まだ完成していません。)
 LHarc1.13cあたりのソースを参考に作ったものらしいということです。
吉崎さんは、もう完全なソースは公開しないとまで申されていますが、他機種への
移植も考えて、少なくともC版は公開していただきたいものです。
 バイナリエディットによる単純な偽物を防ぐためには、どこかに自分自身のCR
Cを計算する部分をこっそり入れておくという手があると思います。PKZIPも
確かそれに類したことをしていたと思います。もっとも、どんなことしても、その
気さえあれば、外すのは簡単ですが。
 ウィルスについても、そろそろうちの98とPC/ATコンパチ機も、予防策を
考えなければならないと思っています。もっとも、98はまだハードディスクが買
えないので、毎回RAMディスクにCOMMAND.COMを転送して使っている
ので、大丈夫のはずですが、PCコンパチ機が心配です。
 MS−DOSのジェネリックなウィルス対策ソフトはあるでしょうか。
 自分で作った方が速いかな。その方が耐性ウィルスもいないだろうし。もっとも、

ルのCRC計算をすることしか考えていませんが。自分で作れば、CRC多項式を
自由に選べるので、耐性ウィルスの心配はないはずだと単純に考えていますが、も
っと巧妙なウィルスもあるのでしょうか。
 それから、またLHのことですが、吉崎さん、ファイルサイズとCRCを発表し
ていただければ、偽物はすぐ見分けられます。ほんとはCRCを合わせるのはたや
すいことなのですが、一般には難しいと思われているようなので……。32ビット
のCRCなら試行錯誤で合わせるには2の32乗回も計算しなければならないので、
試行錯誤以外の手口を知らない人にとっては、難しいのでは? 複数のCRC多項
式を使えばさらにCRC合わせが難しくなるでしょう。本当はそれも(こちらの使
う多項式の組さえわかれば)簡単だったりするのですが……。そうだ、さらに難し
くするためには、ビット列を逆に走査して計算したCRCも含めればいいのでは…
…? これらのCRC破りの問題を数学的に考えられた方は、ボードではなく、メ
イルで、関係者だけにお知らせください!
 素因数分解を使う暗号ならもっと安全かな。
 ちなみに、CRCといっても、左送り、右送り、0で初期化するもの、0xFF
FFで初期化するもの、後者ではさらに結果を反転するものとしないものなど、い
ろいろあるようです。CCITTでは0xFFFFで初期化することを推賞してお
り、ISHはそれに準拠しているようです。こうしないと、ある種の化け(頭にN
ULがいくつも付く)に対して無力です。伝送の際にはこのような化けはけっこう
あるようなので。アーカイバの場合は大丈夫だと思います。
#2094/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/ 4  13:39  ( 46)
Adjusting CRC
★内容
  CRC合わせについて, ちょっとだけ書きます. \LaTeX\ の
記法を使います. あまり易しくは書きません.
  データを $d$ とすると, CRC-CCITTのチェックビットは
$dx^{16}$ を $x^{16}+x^{12}+x^5+1$ で割った余りです.
係数の計算はすべて mod 2 で行います. これがいま $r_1$
だったとすると,
  \[ dx^{16} \equiv r_1 \pmod{x^{16}+x^{12}+x^5+1} \]
となります. 最後から $k$ ビット遡ったところからの16ビ
ット $a$ でCRCを $r$ に合わせるには,
  \[ dx^{16}+ax^{k+16} \equiv r \]
とすればよいので,
  \[ ax^{k+16} \equiv r + dx^{16} \equiv r + r_1, \]
つまり
  \[ a \equiv x^{k+16}(r + r_1) \]
となります.
  \[ x^{16}+x^{12}+x^5+1 \equiv 0 \]
ですから
  \[ x(x^{15}+x^{11}+x^4) \equiv 1 \]
となり,
  \[ x^{-1} \equiv x^{15}+x^{11}+x^4 \]
です. この $k+16$ 乗を $r + r_1$ に掛ければ $a$ が
求められます. 工夫すれば$n$乗は $O(n)$ でなく
$O(\log n)$ のオーダで求められますから, ほんとにあ
っという間に合わせられるはずです. 2つ以上のCRCキー
を合わせるには Chinese Remainder Theorem を使います.

  以上は理論で, まだ何もやってみていません.

  吉崎さん, 実験をされたそうですが, ぜひ実験方法と
結果をお知らせください.

  ただし, あまり誰にでもできるCRC合わせのアルゴリズム
が発表されてしまうと, ウィルス作りの人が {\tt chkcom}
のようなプログラムを簡単に破れるようになりますので,
困るかもしれません. {\tt chkcom} などが改良されるまで
は, もしそういうプログラムを作られた方は, 内輪だけに
配った方が安全かもしれません. 私はまだ何も作っていま
せん.

  昔のザベでウィルスについての座談会があって, その中
で, チェックサムは簡単に合わせられてもCRCを合わせる
のはたくさんのバイトを調整しなければならないような間
違ったことを書いてありました.

  P.S. A minus sign is missing in the above article.
If you know where, you've understood the idea.
#2096/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/ 5   5:59  ( 10)
CRC多項式の選び方/奥村
★内容
  どんな基準で選べばいいのでしょうか. 16個のチェックビットの
パターンは65536通り. これをどのように振り分けるかによって選び
方が違ってくると思われます. CCITTのものなどは, 32767ビットまで
のファイルなら, どの1ビットまたはとなり合った2ビットが反転して
も, チェックビットのパターンが異なるように選んであります.
もし65535ビットまでのファイルでどの1ビットが反転してもチェック
ビットのパターンが異なるようにしたいなら, 別の多項式 (たくさん
ある) を使わなければなりません. ウイルスのような酷い誤りを見つ
けるだけならほとんどどんな多項式でもいいと思います (もっとも x
で割り切れては困りますが).
#2097/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/ 5  11: 2  ( 31)
CRCについてまたまた/奥村
★内容
  CRCは要するにデータのビット列を多項式と見て
ある多項式 (生成多項式) で割った余りをチェックビット
とするものでした. ただし係数の計算は mod 2 で行います.
数学の言葉でいえば, 0 と 1 だけの世界, ガロア体 (Galois
field) GF(2) の世界で係数を計算します. n次の多項式で
割った余りだけを考えるなら, 余りは n - 1 次の多項式です
から, 係数は n 個あり, それがおのおの 0 または 1 の値を
とる世界, GF(2^n) の世界の話になります.
  多項式の世界で素数に当たるもの (より次数の低い多項式
で割り切れないもの) を既約多項式 (irreducible polynomial)
といいます.
  さて, 1, x, x^2, x^3, ..., という列を生成多項式で割った
余りを考えましょう. ずうっと続けていくと, また元の 1 に
戻るはずです. その周期は, 16ビットのCRCなら, たかだか
65535です. 65536ではありえません. なぜならこの周期の中
に0は含まれ得ないからです.
  生成多項式が既約でなければ, 上の周期は65535に満ちません.
しかし, 既約であっても周期が65535になるとは限りません.
周期が65535になる生成多項式を原始多項式 (primitive
polynomial) といいます. 17次の原始多項式を数えたら2048個
ありました.
  ちなみに, 既約多項式の係数を左右逆に並べた多項式 (reciprocal)
はまた既約多項式です. 原始多項式を左右逆にしたものもまた
原始多項式です.
  CCITTやANSIの生成多項式は原始多項式ではありません. これら
はそもそも x + 1 で割り切れるので既約多項式ではありません.
これらは
  1, x, x^2, x^3, ..., x^{32766},
  x + 1, (x + 1)x, (x + 1)x^2, ..., (x + 1)x^{32766}
がすべて異なるCRC値をもつように選ばれているようです. 数えて
みたら, このようなものは1800個ありました.
#2098/3340 計算機と算法    *** コメント ***
★タイトル (SCIENCE )  90/ 5/ 5  13:37  ( 11)
CRC(続き)/奥村
★内容
  まず訂正. 1箇所16次というのが17次になっていました.
  ではどうしてこういう符号をcyclicというかというと,
じつは本当はCRCはcyclicではないんです. ただし, こう
いう GF(2) の16次の原始多項式を使えば, 65535ビット
をぐるりと巡回置換してもCRC値は代わりません, そうい
う特別な長さの場合だけcyclicなのです.
  なぜかといえば, 65535ビットをたとえば左回りに1ビッ
ト巡回することは, xを掛けて x^{65535} + 1 で割ること
にあたります. ところが, 周期が65535なのですから,
1 と x^{65535} とのCRC値は同じです. ですから
1 + x^{65535} は生成多項式で割り切れるというわけです.

次の書き込みはプログラムが lha 圧縮して ish 化して入っていましたが, ここでは復元しておきました。 タブは4桁にして読んでください。

#2099/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/ 5  17:34  ( 34)
CRC(また続き)/奥村
★内容
  周期65535 (32767) の生成多項式を列挙するその場かぎ
りのプログラムです:

crctest.c

  いろいろなことをやっていますが, ほんとは d_min をちゃんと
見つけるプログラムを書きたいのですが, まだよくわかりません.
  ウイルス対抗策というだけでなく, ishの誤り訂正率を良くする
ことはできないかという問題意識もあります.
  ishでは内部形式になおしてから縦横斜めにチェックキーをつけ
ていますが, エラーはたぶん元の文字単位で起こるのでしょうから,
元の文字のままで縦・斜めチェックを入れられないか, 各行にCRCを
つけるならついでにそれで誤り訂正も少し (1ビット) くらいなら
できないかなどと考えています.
  CCITTやANSIの生成多項式が x + 1 で割りきれるのは, 32767ビ
ット以下のブロックごとに使うことを想定したためだと思います.
たとえばishが各行にCRCを使ったりXMODEMが128ビットごとにCRCを
使ったりするのは良いのですが, LHarcなどはまったくこの意図に
沿わない形でこれを使っているわけです. むしろ GF(2) の原始多
項式 (周期65535の最大周期列を生成する) を使うべきだったかも
しれません.
#2101/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/ 6  13:41  ( 24)
CRC(またまたまた)/奥村
★内容
  この前の続きです. 尻切れのままで申し訳ありませんでした.

  実際, CCITTやANSIのものではブロック長が32767を超えると d_min
が 2 になってしまいますが, 原始多項式なら65535まで d_min は 3
です. これは, d_min というのはそもそも許される符号語のうちで
1のビットの数の最小数であることから導けます (線形なので, すべ
て0という符号語からの距離だけ考えればいい). 65535ビットのうち
どれか一つだけが1であるような場合は, 最大周期列の定義からして
すべて異なるCRC値になるはずですが, そのような1を二つ重ね合わせ
てCRC値を0にはできないのですから, d_min = 2 ということはありま
せん. 二つ重ね合わせて1にはできるでしょうから d_min = 3 という
わけです. それでも, ブロック長が65535を超えると d_min = 2 にな
ってしまいます. つまり, 1ビットの誤りは見つかるけれども, 2ビッ
ト以上の誤りは帳消しになって見つからないかもしれません. d_min
= 3 なら2ビットの誤りまで確実に見つかります.
  32767ビットというのは4Kバイトで, それ以上のファイルに一つし
かCRCキーを付けないなら, 原始多項式に軍配が上がるはずです (だ
と思います. みんなCCITTやANSIを使っているので少々自信がありま
せんが).
  考えながら書いているので, 文章がおかしいかもしれません. ご
容赦ください.

  吉崎さんと私とでCRC合わせのプログラムを作っていますが, ウィ
ルスの発育を助長するのではないかと思って発表を見合わせています.

UFD さんから上の crctest.c が無限ループにならないかと質問がありました。

#2103/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/ 8   5:57  ( 14)
UFDさんCRCTESTについて/奥村
★内容
    if (r & 1) r = (r >> 1) ^ poly;
    else       r >>= 1;
は, レジスタ r を左右逆に使っているのでちょっとわかり
にくいかと思いますが, 本来なら >> は << で, 多項式は
左に一つずらすということは x を掛けていることにあたり
ます. それで16ビットからはみだすビットが1なら poly と
xor をとっていますが, これがじつは生成多項式 poly を
法とする剰余計算をしているわけです. ふつうの CRC 計算
ルーチンと同じことです. つまり, x, x^2, x^3, ... と順
に x を掛けていって, poly で割った余りだけ残していく.
それは 0 を除いた 1..65535 を順にとるはずですから, 最
大周期は65535です. いつかは r == 1 に戻ってくるので,
無限ループにはならないのです. 戻ってくるまでの周期を
i で数えています.

UFD さんはすぐに拙作 crctest.c を改良してくださいました。

ROM男さんが Brent の論文を FAX で送ってくださいました。

#2111/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/11   6: 6  ( 54)
圧縮>重要論文/奥村
★内容
 ROM男さんから昨夜FAXで送っていただいたものです。まだ完全に理解して
いませんが、もしかしたら今やっているものよりこちらの方がいいかもしれません。
検討をお願いします。なお、X68Kのishでは新ishフォーマットが復元で
きないようなので、旧ishを使って送ります。

brent.txt

 それから、圧縮の本を一つ米国から取り寄せましたので、これもそのうちに紹介
します。CACMの新しい号にも何か圧縮関係で載っています。しかし、時間がな
い。今日は断れない飲み会。
 昨日は某出版社の人が来ていろいろ情報交換をしました。
 UFDさんのcrctestは、結局どこが違うのかわかりませんでした。同じ
ような感じですが。1がsになっていましたが。
 16元方程式で任意の16ビットで合わせられるわけですね。なるほど。しかし
まあ実際には連続した16ビットで十分でしょうが。
#2113/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/12   5:58  ( 26)
圧縮>Brentの算法など/奥村
★内容
 説明不足でしたが、このアルゴリズム、まだよく理解していないのですが、ちょ
っとLZWみたいに見えるけれども、論文に書いてあることによれば、完全な最大
一致列を見つけることができるということです。もしそうなら、圧縮比はわれわれ
の方法と変わりません。
 もう一つ入手した本は、
    Timothy C. Bell, John G. Cleary, and Ian H. Witten,
    Text Compression (Prentice-Hall, 1990)
というものです。この前ここで紹介したACM CSの論文と同じ著者で、内容も
ただあれをふえんしただけのもののようです。CACMに載った算術圧縮のC算譜
も収録してありますので、そちらの方を持っておられない方は、買う価値もあろう
かと思います。丸善に注文してもいいでしょうが、私は直接Prenticeに手
紙を書いて送ってもらいました。代金はマスターカードの番号(とexp.dat
eとsignature)を書いておけばそちらから引き落としてくれます。
 もう一つ、新しいCACMの記事は、ハフマンなど接頭符号の復号法をいろいろ
書いてあるようですが、まだ良く読んでいません。

 蛇足:算譜=プログラム、算法=アルゴリズム、作譜=プログラミング。これら
は計算機科学からなるべくカタカナを追放しようという人たちが提案する用語です。
 ACM=米国の計算機関連の学会。ACM CS=ACM Computing
Surveysという雑誌。CACM=Communications of
the ACMという雑誌。

 追伸:ROM男さん、.dviどうも。まだ解凍してませんが、日本語が入って
いると私のTeXでははじかれてしまうんでしょうね。アルゴリズムをこのような
形で書いてあるのをTeX化しようとするとけっこう面倒です。WEBのような
フィルタ(WEBでなかったかな)をかけると簡単にちゃんとなるのでしょうか。
#2116/3340 計算機と算法    *** コメント ***
★タイトル (SCIENCE )  90/ 5/12  19:24  (  2)
圧縮>Brent/奥村
★内容
 吉崎さんに、あれでは最大一致文字列は見つからないのではないかと言われ、
考え込んでいるところです。
#2117/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/12  20:39  ( 34)
圧縮>Brentもう一度/奥村
★内容
もう一度, 問題の部分. 前回は無理に訳してしまったので,
ニュアンスがわからなくなってしまったかもしれません.
こんどは原文のまま書きます:

  if match then
    begin
    represent the matching entry in H by (k, m);
    { Save the best match found so far }
    k' ← k;  m' ← m;
    replace the representation of the matching entry in H by (j+1, m);
    if k + m ≦ n then
      enter s_k ... s_{k+m} in H (overwriting any matching entry);
    m ← m + 1
    end
  else
    enter s_{j+1} ... s_{k+m} in H

ここに載せてあるものは, まだ sliding dictionary になる前の,
バッファが無限に大きい場合の算法で, sliding dictionary にする
詳細は, 論文には書いてありません.

問題なのは, ある文字列が見つかったなら, enter s_k ... s_{k+m},
つまり, 一つ長いものを新たに登録する (もし同じものがあれば上書き
する, overwriting any matching entry) ようなのです. そして, 一致
長 m を増やして繰り返しています. ここのところに秘密があるのでは
ないでしょうか.

といっても, おおまかなことしか書いてないので, まだ算譜にできな
いでいます.

ちなみに, この論文では, WeinerやMcCreightの算法 (trieを
使ったもの) も文献を引用していますが, 同じ O(n) でもちょ
っと複雑であまり用いられていないのではないかと書いてあり
ました.
#2122/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/13  19:19  ( 31)
圧縮>Brentデモプログラム/奥村
★内容
  論文の算法をそのまま算譜にしてみました. したがって,
スライド辞書にはなっていません. また, ハッシュ表の衝突
は無視しました. たとえば brent aaaabaaacaaba とすると
a(0,3)b(3,3)c(6,4) と表示するだけのものです. コマンド
ラインの3番目に -d とするとデバッグ情報を出力します.

brent.c
#2130/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/15   2:28  ( 15)
ROM男さんそのとおりでした/奥村
★内容
  私のはものすごく無駄をしていたようです.
\begin{verbatim}
    abcdefg0abcdef1abcde2abcd3abc4ab5abcdefg
\end{verbatim}
について考えていて, 論文でよくわからなかったところが納得できる
ようになりました. それは
\begin{quotation}
  In practice it is sufficient just to check that $h(K) = h(K')$,
  $\|K\| = \|K'\|$, and that the first few bytes of $K$ and $K'$ agree;
  the probability of a `false match' is small and we can check for it and
  backtrack if necessary before encoding $(j - k', m')$.
\end{quotation}
のところです. 途中の abcde などは長さとハッシュ値が合っていたら文字ごと
チェックは省略してどんどん長いものを探し, 最後にチェックして false match
だったら backtrack するということのようです.
#2133/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/16   6:10  ( 41)
吉崎さんのbrent/奥村
★内容
 さすがは吉崎さん、もうできたみたいです。私の ar の slide.c に置
き換えて使ってみてください。Garbage collection はまだしてないので
DICSIZ 分しか読み込みません。hash の計算部分だけをアセンブラにした
ら Trie とほぼ同等になったということです。

slide.c
……略……
#2138/3340 計算機と算法
★タイトル (SCIENCE )  90/ 5/17   5:54  ( 16)
吉崎さんのslide.c/奥村
★内容
  VzエディタをIBM PCに入れて遊んでいまして, まだあまり深く
考えていません. でも, 次の部分はバグではないでしょうか.

    for (i = DICSIZ * 2; i <= MAX_HASH_VAL; i++) next[i] = NIL;
                            ^

  吉崎さんの出された例

    F:\TC>brent abcdef0abcdef1abcdef2bcdef
    abcdef0(6,6)1(6,6)2(19,5)
                        ^^

考えてみましたが, 簡単に修復する方法は思いつきません.
われわれの方法では最近接一致位置を求めることが本質的
ですから, このままでは残念ながら brent は駄目のようです.
やはり trie しか道はないのでしょうか.

このころはもう「計算機と算法」ボードの話題は TeX が多くなっていました。 吉崎さんの LHA(当時は LH と呼ばれていた)は遅々として進まず, やっと1990年7月27日に NIFTY にオールC言語の試作版 LHx が出ます。 翌28日には「計算機と算法」に転載しました。 しかし実は吉崎さんの README には次のように書いてあります。

 このバージョンは、NIFTY-Serve の flabo のみで公開します。転載はあまり
ましくないのですが、圧縮・復元アルゴリズムの検討や、他のOSへの移植のた
めに転載される場合にはかまいません。フリーソフトウェアを普及させるための
転載や、会員へのサービスを目的としての転載はお断りします。また、必ずソー
スを転載して下さい(実行ファイルのみの転載は認めません)。

Huffman 木の長さが16ビットを超えると高速な実装が面倒になるので, 長さを16ビットに制限するための部分を, 吉崎さんとROM男さんと私とで競争で書きました。

#2374/3342 計算機と算法
★タイトル (SCIENCE )  90/ 8/ 9  18:51  ( 44)
新adjust/奥村
★内容
 吉崎さんのものを最初から書き直していたら、なんとなく納得のいくものができ
ました。吉崎さんやROM男さんと考えていることは同じなのでしょうか、なんと
なく自己流にきれいに書けると分かった気になるものです。吉崎さん流にいうと、
cumの右から見ていって、1のビットを消していきます。ROM男さん流にいう
と、下の長すぎるところの部分木を、上に寄せてていって、空いているところがあ
ればそこに移植します。思い違いがあるかもしれませんのでチェックしてください。
 これを使ったmaketree全体も書いてみました。コード生成部は吉崎さん
のmaketblに習って効率化しました。ところが、他もいろいろいじったので、
どこかで同期がとれなくなってしまって、現在arは動作しない状態です。
……略……

このころになると,手抜きをして一つの書き込みの中で圧縮のことや TeX のことなどをごっちゃに書くことが多くなり, タイトルも手抜きで「いろいろ」というのが多くなりました。

#2375/3342 計算機と算法
★タイトル (SCIENCE )  90/ 8/ 9  18:54  ( 49)
いろいろ(また手抜きタイトル)/奥村
★内容
 (これは朝書いたものです。)
 吉崎さん、こちらにも出てきていただいてありがとうございます。
>  Tri−P経由だと、アップロード時に改行待ちにしても行が飛ぶこ
> とがあるようなので、なかなかこちらに書き込めないでいます。この文
 PC−VANの通常のアクセスポイントは^Mをエコーバックし、少し遅れてホ
ストが^Jをエコーバックするので、^Jを待ってから送ればいいのですが、Tr
i−Pはどうなっているのか不明です。いずれにしてもプロンプト>はホストが返
すのでしょうから、>待ちにするしかないようです。行末の文字欠けといい、PC
−VANのホストのファイルシステムの悪さはさんざん文句を言われながら改善さ
れないですね。PC−VAN経験者は迷わず富士通のメインフレームを導入するで
しょう。ただし富士通のエンジニアにはバックアップをとらせないとか……。
 SOLITONさん、言い遅れましたが、邦訳ありがとうございます。これで私
も……といいたいところですが、訳を読ませていただいたかぎりでは、マウスが必
要のようですね。残念。どこかIBMPC用のマウスを安くで売っているところあ
りませんでしょうか。TurboPascalだそうですからソースを入手できれ
ば98用にリコンパイルできるでしょうけれども、シェアウェアじゃ無理か。
 CompuServeでもIBMPROの圧縮ボードではあまりまともな話はあ
りませんが、メイルでいろいろ貴重な情報を教えていただけることがあります。向
こうではどうもアルゴリズムは簡単に公開せず金にするような感じです。arをい
ろいろ試してくれた人の話では、吉崎さんのmake−treeはかえって遅くな
ったとか言っています。なにかおかしいことでもしているのでしょうか。LHxは
長いので送っていませんが、先日のmake_treeだけ送ったところarと組
み合わせてテストしてくれています。16ビット修正用はまだ送っていません。と
ころが、あのarのバグっている16ビット修正部分、まず問題はないだろうとさ
ぼっていたところ、ついに200kほどのファイルであのInternal er
rorというメッセージが出たそうです。やはり16ビットを超す場合もあるんで
すね。
 MacでCompactorという新しい圧縮ソフトが出たそうです。私にメイ
ルをくれた人は、その作者に手紙を書いてみたが、アルゴリズムについては教えて
くれないそうです。arとの比較では、多くのファイルでarが勝つとのことです。
 私のarでは、まず起こらないことには手抜きするという方針で、16ビットを
超えたものはみな16ビットに直し、その分15ビット以下のものを何でも16ビ
ットにしてしまうことを、プリフィックスコードができるまで繰り返し、あとは知
らんぷりというアルゴリズムです。当然オプティマルなプリフィックスコードはで
きません(吉崎さん流にいうとcumulateが0x10000未満になります)。
それでもちゃんとプリフィックスコードができるので、放っておくことにしました
が、問題はそこから後にあり、もう一度コードを最編成するところ(すぐ上)はオ
プティマルなコードを仮定して作ったものに手を加えなかったので、混乱してしま
うというわけです。今huf.cを見直してびっくりしました。
……略……

次の改良版 ar というものが,海外で ar002 として配布されていたものです。 たとえば Mark Nelson の The Data Compression Book (M&T Books, 第2版: 1996, ISBN:1-55851-434-1) の付録ディスクに収録されている ar002.exe という自己解凍ファイルがこれに相当します。

#2389/3342 計算機と算法
★タイトル (SCIENCE )  90/ 8/15   5:35  ( 55)
圧縮>ar(poor man's LH)改良版/奥村
★内容
 ヘッダをLHxもどき(レベル1)にしてみました。あと、いろいろバグやら能
率の悪いところを直しました。ANSI準拠です。タイムスタンプ表示はあきらめ
ました。圧縮アルゴリズム部分だけを自由にいじっていろいろテストしてみたい方
向きです。圧縮時のワイルドカード展開はしませんので
   for %f in (*.c *.h) do ar a test.ar %f
のようにしてください(%fがだめなら%%f)。無断転載無断改変等歓迎。
……略……

このように私の書いたものはいつでも「無断転載無断改変等歓迎」 としていました。今でいうオープンソースの走りですね。 このいわゆる ar002 には一つだけコンパイラ依存のバグがあります。 maketbl.c の24行目の

    while (i <= 16) weight[i++] = 1U << (16 - i);
は当時の Turbo C で通ってしまったので気付かなかったのですが,ほんとうは
    while (i <= 16) {
        weight[i] = 1U << (16 - i);  i++;
    }
とすべきでした。これ以外のバグは報告されていません。

同じ1990年8月15日に,吉崎さんから改竄版 LHarc についてのお知らせが入りました。 当時はインターネットがなかったのでオリジナルの配布先がわかりづらく, 電子署名なども一般的でなかったので, 転載を経ているうちに改竄されていることがときどきありました。

1990年9月12日あたりから,CP/M 上の PMarc が話題になっています。

#2487/3351 計算機と算法
★タイトル (SCIENCE )  90/ 9/14   5:51  ( 19)
PMarc&TUGboat9月号/奥村
★内容
 PMarcのアルゴリズムは、10Kのスライド辞書だそうです。ハフマンの代
わりに、各文字に一番最近現われたものから順に0から255までの番号を振り、
番号の小さいものほど短い符号を割り当てるということです。速いのは、アセンブ
ラで十分最適化してあるからのようです。
……略……
#2518/3351 計算機と算法
★タイトル (SCIENCE )  90/ 9/26   5:37  ( 68)
% Length-Limited Huffman Codes / H.Okumura
★内容
\newenvironment{englishonly}{\par\setlength{\baselineskip}{1.2em}}{\par
  \vspace{.3em}}
\begin{document}
\noindent 次のような論文がありました.
\begin{englishonly}
 \begin{quote}
  Lawrence L. Larmore and Daniel S. Hirschberg.
  A Fast Algorithm for Optimal Length-Limited Huffman Codes.
  {\it Journal of the ACM}, 37:\,464--473, 1990.
     % この文献の表し方は van Leunen 流. %
 \end{quote}
 Abstract.
 An $O(nL)$-time algorithm is introduced for constructing
 an optimal Huffman code for a weighted alphabet of size $n$, where
 each code string must have length no greater than $L$.  The algorithm
 uses $O(n)$ space.
\end{englishonly}

まず次の問題を考えます (Coin Collector's problem).
要素の個数 $m$ の集合 $I$ があります.
各要素には幅と重さがあり, 幅は2の整数(負でもよい)乗です.
$I$ の部分集合で幅の和がちょうど与えられた値 $X$ になり,
重さの和が最小になるものを求めるのが問題です.

要素をあらかじめ重さの順に整列しておけば
次の $O(m)$ の算法で解けます.
以下で diadic expansion とは2進展開のことです.

\begin{englishonly}
 \begin{quote}
  \setlength{\parskip}{0em}
  \renewcommand{\.}{\hspace*{1em}}
  \renewcommand{\=}{\leftarrow}
  \obeylines
  $S \= \emptyset$
  for all $d$, $L_d \=%
    \mbox{list of items having width $2^d$, sorted by weight}$
  {\bf while} $X > 0$ {\bf loop}
  \.${\it minwidth} = \mbox{the smallest term in the diadic expansion of $X$}$
  \.{\bf if} $I = \emptyset$ {\bf then return} \lq\lq No solution.''
  \.{\bf else}
  \.\.$d \= \mbox{the minimum such that $L_d$ is not empty}$
  \.\.$r \= 2^d$
  \.\.{\bf if} $r > \it minwidth$ {\bf then return} \lq\lq No solution.''
  \.\.{\bf else if} $r = \it minwidth$ {\bf then}
  \.\.\.Delete the minimum weight item from $L_d$
  \.\.\.\.and insert it into $S$
  \.\.\.$X \= X - \it minwidth$
  \.\.{\bf end if}
  \.\.$P_{d+1} \= {\rm PACKAGE}(L_d)$
  \.\.discard $L_d$
  \.\.$L_{d+1} \= {\rm MERGE}(P_{d+1},L_{d+1})$
  \.{\bf end if}
  {\bf end loop}
  {\bf return} \lq\lq$S$ is the optimal solution.'' %
 \end{quote}
 {\sc The Step PACKAGE}. \ The list $P_{d+1}$ is formed
 from $L_d$ by combining items in consecutive
 pairs, starting from the lightest.  That is, the $k$th item of $P_{d+1}$
 is the package formed by combining items $(2k-1)$ and $2k$ of $L_d$.
 If $L_d$ is of odd length, its heaviest item is simply discarded.
 The MERGE step is just the usual merging of two sorted lists.
\end{englishonly}

Length-limited Huffman の問題は上の問題に帰着できるというわけですが,
時間がないのでここまで.
\end{document}
#2532/3351 計算機と算法
★タイトル (SCIENCE )  90/ 9/29   5:39  ( 35)
差分アルゴリズム/奥村
★内容
MASSANの挙げておられた
\begin{quote}
    Webb Miller.
    {\it A Software Tools Sampler}.
    Prentice-Hall, 1987.
\end{quote}
は確か以前パラパラと目を通して, サイズ $m$, $n$ のファイル
の差分を求めるのに $O(mn)$ の場所が必要であるように思って,
これでは使い物にならないと早合点して追究を止めてしまったの
だと思います. これが私が以前\#2332で {\it wanted\/} リスト
に挙げた論文の一つ
\begin{quote}
    Eugene W. Myers.
    An $O(ND)$ difference algorithm and its variations.
    {\it Algorithmica}, 1:251--266, 1986.
\end{quote}
の解説になっていることは気づきませんでした. ただしMillerの
本によればこのアルゴリズムが初めて現れる文献は
\begin{quote}
    W. Miller and E. W. Myers.
    A file comparison program.
    {\it Software---Practice and Experience}, Nov.\ 1985, 1025--1040.
\end{quote}
だそうです. さらに, {\it diff\/} タイプのスクリプトでなく三木さんの
{\it Ldiff\/} タイプのもの (copy, append) を使うアルゴリズムの文献が
\begin{quote}
    Walter F. Tichy.
    The string-to-string correction problem with block moves.
    {\it ACM Transactions on Computer Systems}, Nov.\ 1984, 309--321.
\end{quote}
にあると書いてあります. これらの文献も {\it wanted\/} リストに加えま
す. とりあえずはMillerの本を少し勉強します (本当は昨日読もうと思った
のですがあわただしくて\ldots. 今日--明日は久里浜高校の文化祭です.
立ち番の間に目を通そうと思います. お暇でしたら文化祭を見に来てくださ
い.
#2536/3351 計算機と算法
★タイトル (SCIENCE )  90/ 9/30   5:44  ( 52)
MASSANの差分器/奥村
★内容
まずどうでもいいことから.
\begin{quote}
ある文字列sのi番目に始まる長さjの部分を s[i:j] と表すことにしま
しょう。
\end{quote}
Millerは
\begin{quote}
ある文字列sのi番目からj番目の部分を\ldots
\end{quote}
のつもりで使っているのではないでしょうか ($i = 1$ なら同じこと).
\begin{quote}
ファイルの比較のように,全部メモリに載せて比較するわけに行かない場合
どうしたらいいか。
\end{quote}
これについてはMillerの本112ページの中ほどに
\begin{quote}
  in the paper cited above, Gene Myers shows how the algorithm can be
  modified to run in space proportional to $m + n$.
\end{quote}
とありますので, もう少しスペース効率を良くする方法はあるのでしょ
うね. しかし, $O(m + n)$ でもメモリから溢れるときは,
適当な heuristic を使って初めの部分から捨てていくことになるのでし
ょうか. たしか ldiff はそうしていたと思います. GNU diff はどうや
っているのでしょうか.

ldiff は三木さんが ``さぼっている間に bdiff/bupdate に追い越された
ので何か良いアイデアはないか'' という意味のことを NIFTY に書いてお
られましたが, その後は不明です. まず, diff タイプの insert/delete
script よりもやはり copy/append script の方が小さくなりそうな気が
しますがどうでしょうか. それなら新 LH の trie でファイル1 (サイ
$m$)のすべての長さ256までの文字列の辞書を $O(m)$ の手間で作ってし
まい, それに照合しながらファイル2を符号化していくのが速いのでしょ
うか. それと差分の表現の問題があります. 80x86 の実行ファイルの差分
を表現するにはどんな方法が良いのでしょうか. ちょっと前の方を変えた
だけでアドレスがみんな狂ってしまいます. テキストファイルみたいにう
まくいきません. 80x86 の命令を知った差分器が必要でしょうか.

MASSAN 作 Mdiff を期待しています. 三木さん, 吉崎さんの次のヒーロー
は MASSAN かも?

{\tt myers.c} は楽しませていただきました. アルゴリズムのリアルタイ
ムの図解がいいですね (ただし少し遅くしないと目に止まらない).
{\tt instr()} は
    i = 0;
    while ((c = getchar()) != EOF && c != '\n')
        if (i < MAXLIN && ! isspace(c)) s[i++] = c;
    s[i] = '\0';
のようにしないとリターンキーを打たないで ^Z (UNIX なら ^d) を打つと
無限ループになりそうです.

どうもまだ差分のことについては頭が回り始めないのでトリヴィアルなこと
ばかりですみません.
#2706/3361 計算機と算法
★タイトル (SCIENCE )  90/11/10  19:56  ( 22)
arj014についてなど/奥村
★内容
 ANSI Cで書いてあるとか圧縮比とかから考えてar001に他のアーカイ
バにあるいろいろな機能を付けたもののようですね。このar001はずっと前の
もので16ビットを超える符号語については吉崎さんから指摘されたようにバグっ
ていたりするのですが……。ar001のソースにはちゃんとIDを書いておいた
ので連絡してくれれば新しいのがあることを言えたのですが(Internetか
らCompuServeへはemailを双方向に送れる)。新しいar002は
CompuServeのIBMPROに入っています。Kayaさんに頼まれて送
ったもので、ISHで送ったのですがちゃんとバイナリに直してライブラリに入れ
てくれています。こちらからメイルするのも面倒ですが。
 arjは、せっかくANSI Cで書いたのですからソースで提供すればいいと
思うのですが、商業指向かな。実行コードだけの提供ならANSI Cで書いたと
いう宣伝文句はあまり意味がありません。むしろTurbo Cでコンパイルした
と言った方が適切かも(Turbo Cでコンパイルした痕跡があります)。
 ところで、いまCIS(=CompuServe Information S
ervice)に入ってきたのですが、Wolfram Research(あの
Mathematicaを作ったところ)がCISに出店を出したということです。
また、この前ar002を読んだある人が「Pascalに直すかアルゴリズムの
詳しい解説をするかしてくれないか」と言ってきたので「いま圧縮の原稿で忙しい。
そちらでもパブリッシュしてくれる雑誌があれば英訳してもいい」と半ば冗談に言
ったのですが、そうしたら「こいつなら絶対大丈夫」と某パソコン雑誌の編集者の
アドレスを送ってきました。吉崎さんどうしますか? 英訳などじつをいうと面倒
で閉口しています。
#2712/3361 計算機と算法
★タイトル (SCIENCE )  90/11/11   8:21  ( 30)
arj014についてなど/奥村
★内容
 さらに詳しく読むとar001(002ではない)の影響がかなり見られるよう
です。ヘッダの説明(technote.doc)がまた非常に似ています。ファ
イルタイプでバイナリとテキストを分けたのもar001の発想と同じです。これ
はar001を作った時点ではぜひ必要なものと思っていました。テキストファイ
ルはOSによって構造がかなり違います。MS−DOS(crlf)とUNIX(
lf)はまあ似ていますが、OSによっては行の長さ+行で表すものもあるでしょ
うから、バイナリと見なして読み書きすることは問題があります。でも、ar00
2では単純さとLH互換を考えてこれはなくしました。
 arj014のMethod1−−3はar(LH)方式とほぼ同じようです。
スライド辞書のサイズで分けているんでしょうか。Method4はFiala&
Greene流のunary codeのようです。また、木への挿入も手を抜い
て行う方式のようです。速さはこれが一番でしょう。
 arj014では暗号化は簡単な方法を使っているようです。LHではFEAL
を採用するのでしょうか。キーを初期値として自前の乱数を発生し各文字とXOR
する程度でも、圧縮後に暗号化しヘッダやコメント(無圧縮の部分)は暗号化しな
いならかなり強いとは思います。乱数としては簡単にはキーを8バイトとしハッシ
ュして32ビットに縮め、32ビット合同法乱数を使い、上位8ビットとXORす
れば、ルーチンはC言語で数行でできてしまいますし、速いです。
……略……

ようやく LH ができあがります。

#2767/3361 計算機と算法
★タイトル (SCIENCE )  90/11/20   5:38  (  4)
LH新版出来/奥村
★内容
 NIFTYではアセンブラ版LH2.0の評価版が出ました。なるべく転載しな
いようにとか書いてありましたが、吉崎さん、どうしましょうか?
 ダウンロードしたついでにテディ松本さんのLEXEMという実行もできる速い
アーカイバもいただいてきました。これもこちらに転載しましょうか?
#2785/3361 計算機と算法
★タイトル (SCIENCE )  90/11/23   4:56  ( 23)
LH 2.0 試作版入荷 (ライブラリ/PDS)/奥村
★内容
 吉崎さんの時間的制約のためNIFTY以外では基本的にノーサポートというこ
とですが、それでもかまわないならということでお許しを得て試作版をいただいて
きました。バグレポートや改良案などありましたらこのボードに書いていただけれ
ば、立ち寄られたときに見てくださると思いますが、質問の回答などは期待しない
でください。マニュアルの補遣を以下に挙げます。なお、試作版のため、SFX機
能はありません。
……略……

1990年11月25日,室蘭の大学生だった 岡本継男さん も登場します。 岡本さんはその後 UNIX 版 LHA のメンテをやってくださっています。

次の書き込みの詳細については Efficient decoding of prefix codes をご覧下さい。

#2967/3361 計算機と算法
★タイトル (SCIENCE )  90/12/30   5:10  ( 22)
速いハフマン符号化,TurboC++,etc/奥村
★内容
最近のComm. ACMに接頭符号の速い復号法というのが載っていた
のですがあまり面白そうでないので読んでいませんでした.
Computing ReviewsにHorspool先生が書いているところによ
れば, これより次の方が速いとのこと.
  Y. Choueka, A. S. Fraenkel, S. T. Klein, and Y. Perl.
  Huffman coding without bit-manipulation.  Report CS86-05,
  Weizman Institute, Rehovot, Israel, 1986.
でも新LHより良い方法があるだろうか...
……略……
#2974/3361 計算機と算法
★タイトル (SCIENCE )  90/12/31   6: 1  (  9)
DDJデータ圧縮コンテスト、DIET/奥村
★内容
 1月号のDDJ(米国のコンピュータ雑誌Dr. Dobb’s Journal
のことです)によれば、2月号はデータ圧縮プログラミングコンテストだそうです。
米国内では1月早々に発売されるのでしょうから、早く入手されたかたがおられまし
たら内容を教えてください。日本のCマガに続いて米国でも圧縮ブームなのでしょう
か。UnisysがUNIXのcompressの特許をとって云々ということで、
皆独自の圧縮に頼る傾向が出てきたのでしょうか。
 ところで、Teddy Matsumotoさんの新しい圧縮ソフトDIETをP
DSに入れておきましたが、この日本語版のメッセージはいかがでしたでしょうか?
このメッセージだけでヒット間違いなしです。

リンクはご自由にどうぞ。

松阪大学 奥村晴彦 okumura@matsusaka-u.ac.jp

Last modified: Mon Dec 28 19:44:50 1998