I just had this crazy idea, please help make it real lazarus / 21-General ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 13:27 Hey all, I swear to $DEITY, I got this on the last stages of REM, just before waking up, that's how crazy it is. In the dream Simple premise: Transform a binary file into whatever necessary amount of words in order to make it possible to send it to another person via a dictation, conversation, phone conversation, voice message. The only analogy that quickly comes to mind is the 3 word site that wants to replace GPS. But that's 3 words to 1 square, not really practical when in our situation we'll have an arbitrary number of squares(bytes). What I've thought so far Instead of having a word to byte correspondence, I'm thinking on a bit of optimization(and a pun, of sorts) and have a word to double byte(a word, get it? Nevermind. Though crowd ) correspondence. That would gives us a total of 64KiB of words. Words should not be smaller than 3 or 4 character. Avoid I, it, no... Or would syllable count be better? Maybe syllable count should be greater than 1? One other optimization, I think, would be to have all repeated byte tuples($0000, $0101, ..., $EEEE, $FFFF) to be represented by plural words: apples, oranges, cars.... So that means: 256x256-256 for the amount of singular words and the remaining 256 being plural. Still not sure if this is an optimization or just me grasping at straws. Words should be in alphabetic order. Once randomized on the binary file, they won't be near each other many times. Do not use word for numbers. They can be useful for further optimization. Some thoughts on implementation If this is to be any quick, I need to implement the word to tuple and tuple to word on balanced binary trees. If I implement this on case...of, I don't even want to know the penalty I'll incur. 1. This means that I need to have the binary include the tools to build said binary tree at runtime OR 2. Have a big ass constant created by an external utility OR 3. Include a binary resource of an unmarshalled binary tree construct with the data, then marshall that up into the objects. This blob would be created by some util. Any thoughts on these 3? Probably attempt to calculate the (whatcha-ma-call-it) phonetic distance between words, so that consecutive tuples don't get mixed in a noisy line? Humm, this makes sense if we transmit the tuple list in order. Doesn't make sense in a real situation, where the randomness of the encoded file comes to bear. Ok, Scrap that. This is beginning to feel a bit compilerish, ain't it? Or is it more non dynamic Huffman? Could we make it dynamic Huffman!??! Getting all giddy now... Some far fetched parallels I once read that by using phase switching and/or amplitude switching, ADSL was able to send 4 bits at at time. I know that this is bytes and not bits, but could something like this be achieved? I haven't studied Computer Science and I don't know enough to be able to reduce this problem with a clever table or method, if it exists. I'm thinking about the logic tables in electronics to get at the minimum states. Don't re-invent the wheel As anyone stumbled on such a thing? Cheers, Gus ---------------------------------------------------------------------- MarkMLl · 2021-03-31 13:42 First thought: look at algorithms for LZ compression, e.g. as used in GIF files (which is something I was doing a couple of weeks ago) with the output sequence transcribed to words rather than bit patterns. MarkMLl ---------------------------------------------------------------------- Martin_fr · 2021-03-31 13:55 Don't know what already exists, but.... Choose the words in a manner that you can calculate the double-byte from each word (i.e. like a simple hash). Obviously there will be several words for each double-byte, but you can pick one and use that one. So your decoding needs no lookup (not even a list of the words) and will be fast. If you choose all words between 4 and 10 letters, then you can pad them all to 10 letters, and have a list (655,360 Bytes) in memory to look them up for encoding. If you store the words without padding (assuming an avg of 7 letters, you need 7*65536 PLUS a lookup table. The table could be offsets (integer) and would be 4 * 65536. So your total 11*65536 would be bigger.) ---------------------------------------------------------------------- MarkMLl · 2021-03-31 14:01 Of course, one has to beware of /this/ problem https://www.revk.uk/2011/11/correcthorsebatterystaple.html :-) MarkMLl ---------------------------------------------------------------------- VTwin · 2021-03-31 14:02 Are you thinking of something like this: https://en.wikipedia.org/wiki/YEnc ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 15:02 Hey Mark, Quote from: MarkMLl on March 31, 2021, 03:42:16 pmFirst thought: look at algorithms for LZ compression, e.g. as used in GIF files (which is something I was doing a couple of weeks ago) with the output sequence transcribed to words rather than bit patterns. Can I, confidently say, that LZ compression and dynamic Huffman are a tad interchangeable? Or are the principles behind each one very dissimilar? Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 15:19 Hey VTwin, Quote from: VTwin on March 31, 2021, 04:02:07 pmAre you thinking of something like this: https://en.wikipedia.org/wiki/YEnc No not really. I don't want it to be good for places where you can't have chars outside of [a-zA-Z0-9] etc, that's what uuencode and base64 are for. My intent is to produce a text file that you can read out loud, dictate in the following form: Always 4 words per line preceded by a line number to keep track. Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 1. brown fox lazy dog // This would be the encoding sig like the ones in other bin files2. blue rats friend ball3. coin place under brief.... The decoding ring part of the program would then spit out the tuples by looking at the table/binary tree that contains the association of the word and the tuple. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i case AWord of  'blue': Result:= $0123;  'rats': Result:= $0101;{etc, etc, etc until 64KiB words}end; And maybe use a bit more of the initial lines to encode the filename and, most important, the extension of the original file. Mainly because this could be a zip file, or an image or whatever. I'm also thinking you can encode a folder/many files, in the same way a zip/tar.gz archive can, by having the GUI program zip them first and then encoding it... Does that make it any clearer? Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 15:21 Hey Mark, Quote from: MarkMLl on March 31, 2021, 04:01:15 pmOf course, one has to beware of /this/ problem https://www.revk.uk/2011/11/correcthorsebatterystaple.html :-) Oh, absolutely, LOL!!! But, it's a one time thing, right, not the password you have to give every time a client comes round and ask for a bit of WiFi, right? Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 15:27 Hey Martin, Quote from: Martin_fr on March 31, 2021, 03:55:40 pmDon't know what already exists, but.... Choose the words in a manner that you can calculate the double-byte from each word (i.e. like a simple hash). Obviously there will be several words for each double-byte, but you can pick one and use that one. So your decoding needs no lookup (not even a list of the words) and will be fast. If you choose all words between 4 and 10 letters, then you can pad them all to 10 letters, and have a list (655,360 Bytes) in memory to look them up for encoding. If you store the words without padding (assuming an avg of 7 letters, you need 7*65536 PLUS a lookup table. The table could be offsets (integer) and would be 4 * 65536. So your total 11*65536 would be bigger.) Many thanks for the tip, but you're thinking in terms of making it easy for the machine while this whole exercise is to have it easy for the person that is reading it out loud and the person that has to listen and type it down on a keyboard. So, in a sense, this would be more akin to the phonetic alphabet(Alpha, Bravo, Charlie, Delta, Foxtrot, etc) than any binary to [a-zA-Z0-9] kind of exercise. That's covered by the uuencode and base64 type of programs. Cheers, Gus ---------------------------------------------------------------------- Martin_fr · 2021-03-31 16:45 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 05:27:38 pmMany thanks for the tip, but you're thinking in terms of making it easy for the machine while this whole exercise is to have it easy for the person that is reading it out loud and the person that has to listen and type it down on a keyboard. Well then I do not get your idea... The target is to replace each double-byte by one word from a dictionary (words from an English dictionary / but if someone wanted Spanish, Chinese or other). And yeah the words can contain special chars, like Umlauts. In case of Chinese they would be outside A-Z anyway The produced human-words mix would be just a random melange of words. There would be no meaning to it. No grammatical structure, or anything. "bell the goes become bell bound bind done car....". You could insert punctuation, but it would be ignored by the decoder... At least that is what I understood. On top of that you might add some compression (or maybe checksums). All that can be done in such a way that the decoder can calculate the meaning (and/after check for special tokens). ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 18:08 Hey Martin, Quote from: Martin_fr on March 31, 2021, 06:45:08 pmThe target is to replace each double-byte by one word from a dictionary (words from an English dictionary / but if someone wanted Spanish, Chinese or other). And yeah the words can contain special chars, like Umlauts. In case of Chinese they would be outside A-Z anyway Yes, I think you get it now. Encode "human readable word" -> "double byte" Decode "double byte" -> "human readable word" And yes it could be from whatever language dictionary you want. We can then pre-load a binary blob with the encode/decode tables or have each translation be a separate application with the tables has resources RCDATA. Quote from: Martin_fr on March 31, 2021, 06:45:08 pmThe produced human-words mix would be just a random melange of words. There would be no meaning to it. No grammatical structure, or anything. "bell the goes become bell bound bind done car....". You could insert punctuation, but it would be ignored by the decoder... At least that is what I understood. If you look at what I answered to VTwin, it probably illustrates a better picture of what I mean. Quote from: Martin_fr on March 31, 2021, 06:45:08 pmOn top of that you might add some compression (or maybe checksums). The compression is still under heavy thinking. If I go through with some kind of Huffman, it won't be simple Word->tuple arrays/tables/structures. If I go dynamic Huffman, the table evolves as you compress. And it's all very in the air, since Huffman compresses to bits that get shifted into place, and this needs to be outputting words, not bits. The checksums might be a good idea... Hummm, where to put them... Quote from: Martin_fr on March 31, 2021, 06:45:08 pmAll that can be done in such a way that the decoder can calculate the meaning (and/after check for special tokens). Yes, I've already decided that I need some kind of areas to be defined as something else than just Word->Tuple. Like encoding the name, or at least the extension of the original file. Cheers, Gus ---------------------------------------------------------------------- Martin_fr · 2021-03-31 19:03 QuoteEncode "human readable word" -> "double byte" Decode "double byte" -> "human readable word" The other way round ? You start with a binary, you encode it to be a list of human words? Then you have human words, and decode it back to a binary? So what stops you from making a function Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function SimpleHash(w: String): integer;begin  result := 0;  for c in w do // foreach letter    result := result *3 + ord(c);  result := result and 65535;end;Probably a bit more calculation needed. So then that function may return 1 for "red" and 63090 for "blue".... And if you do it correct, there is at least one word, for each number that can be in a double-byte. So when you have a list of human words, and want the binary, you just need to run the above function on each word. To encode, you need to once generate a list of words for each number. (That will be a bit of computing, but it is once only). You then save that list with your program. (embed into the source, so it gets compiled / or make it load able) ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 19:28 Hey Martin, Quote from: Martin_fr on March 31, 2021, 09:03:17 pmThe other way round ? You start with a binary, you encode it to be a list of human words? Then you have human words, and decode it back to a binary? You're absolutely right. Mea culpa, for switching it around. Quote from: Martin_fr on March 31, 2021, 09:03:17 pmSo what stops you from making a function Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function SimpleHash(w: String): integer;begin  result := 0;  for c in w do // foreach letter    result := result *3 + ord(c);  result := result and 65535;end;Probably a bit more calculation needed. So then that function may return 1 for "red" and 63090 for "blue".... And if you do it correct, there is at least one word, for each number that can be in a double-byte. So when you have a list of human words, and want the binary, you just need to run the above function on each word. My goal is to have an arbitrary list of words that I get from a dictionary text file(from natural language, not a bunch of letters in between 2 spaces) on the internet and create a one to one association with all the combinations of 2 bytes. So the word red would be associated with something like $0102. Thats 2 bytes, one is integer 1, the other is integer 2. Never would a word just represent a single byte. I'm finding it hard to imagine other ways to explain this. That's why your function baffles me. I may be sleep deprived and not seeing it, but it doesn't seem that your function will guaranty a one to one relationship with no clashes. You're using multiplicative and additive. Would 2 words with the same letters in different places thwart the uniqueness? Nonetheless, it does intrigue me quite a lot and I'll need to do some tests on it to clear my mental fog and probably see what you're trying to tell me. Quote from: Martin_fr on March 31, 2021, 09:03:17 pmTo encode, you need to once generate a list of words for each number. (That will be a bit of computing, but it is once only). You then save that list with your program. (embed into the source, so it gets compiled / or make it load able) Yeah, that's what I was discussing in my original post under Some thoughts on implementation with the numbered list. I'm quite fond of the idea of binary trees that once built with an external tool can be dumped into a binary blob that can be added to the app via resource RCDATA. You would then have 2 trees, one for encoding and another for decoding. Cheers, Gus ---------------------------------------------------------------------- AlanTheBeast · 2021-03-31 19:42 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 03:27:03 pm The only analogy that quickly comes to mind is the 3 word site that wants to replace GPS. Eh?  W3W want to provide a simple word set to replace addresses ... esp. in locale's where there is no such things as an "address." as we generally use them. GPS is a GNSS (navigation satellite serice).  Good luck replacing that with W3W. If you mean coordinates, W3W doesn't replace that either - it's just a different encoding of a coordinate. ---------------------------------------------------------------------- Martin_fr · 2021-03-31 19:59 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 09:28:33 pmMy goal is to have an arbitrary list of words that I get from a dictionary text file(from natural language, not a bunch of letters in between 2 spaces) on the internet and create a one to one association with all the combinations of 2 bytes. So the word red would be associated with something like $0102. Thats 2 bytes, one is integer 1, the other is integer 2. Never would a word just represent a single byte. When I said "red = 1" I meant "red = $0001". Quote I'm finding it hard to imagine other ways to explain this. That's why your function baffles me. I may be sleep deprived and not seeing it, but it doesn't seem that your function will guaranty a one to one relationship with no clashes. You're using multiplicative and additive. Would 2 words with the same letters in different places thwart the uniqueness? Nonetheless, it does intrigue me quite a lot and I'll need to do some tests on it to clear my mental fog and probably see what you're trying to tell me. The function I gave is a dummy. It will probably not work for the purpose.... Here is one that might work (not tested for the purpose, but if you change the 550 to other values, you will eventually find one that works) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TSynPluginSyncroEditWordsHash.CalcHash(aWord: PChar; aLen: Integer): Integer;var  v, n, p, a, b, c, c1, i: Integer;begin  a := 0;  b := 0;  c := 0;  c1 := 0;  n := 1;  p := 0;  i := aLen;  while i > 0 do begin    v  := ord(aWord^);    a := a     + v * (1 + (n mod 8));    if a > 550 then a := a mod 550;    b := b * 3 + v * n - p;    if b > 550 then b := b mod 550;    c1 := c1   + v * (1 + (a mod 11));    c := c + c1;    if c > 550 then c := c mod 550;    dec(i);    inc(aWord);    inc(n);    p := v;  end;   Result := (((aLen mod 11) * 550 + b) * 550 + c) * 550 + a;end;  Yes, there will be groups of words, that all give the same number. Maybe "red" and "green" both give 1198 => no problem. As long as you find at least on word for every number in 0..65535. From each "clash group" you only use one word. E.g. you use red for 1198, and you do not use "green" at all. However come to think of it. Most human languages have somewhere between 10000 and 20000 words that actually are in use. Looking at https://en.wikipedia.org/wiki/List_of_dictionaries_by_number_of_words => 520000 words for English. But that does not help, unless you want to include words like "pneumonoultramicroscopicsilicovolcanoconiosis". If it should be easy to read out for a native speaker, then you probably are limited to 10000 to 25000 words (depending how educated the speaker is). And no matter how your code works, that is not enough words for 65536 double-bytes. But say you split each byte into 2 nibbles of 4bit, and then encode 3 nibbles (12 bit) into each word, then that might work. You need 8192 words. So you need to tweak the calculation to minimize clashes (a few will be ok). Of course, if you want to maximize the human-words efficiency, then you need to use a lookup table for decoding, as well as encoding. Because that is the only clash-free way. ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 20:11 Hey AlanTheBeast, Quote from: AlanTheBeast on March 31, 2021, 09:42:39 pmEh?  W3W want to provide a simple word set to replace addresses ... esp. in locale's where there is no such things as an "address." as we generally use them. GPS is a GNSS (navigation satellite service).  Good luck replacing that with W3W. If you mean coordinates, W3W doesn't replace that either - it's just a different encoding of a coordinate. Well, I'll admit that replace is a bit strong. I should've added some air quotes there. Maybe the best analogy would be a translation service, more human readable. Akin to what DNS does for human readable domain names and IP addresses. If each domain name would be 3 human readable words and an IP address was a 3 meter by 3 meter square piece of the Earth's surface, right? Thanks for the nudge to correct myself Cheers, Gus ---------------------------------------------------------------------- MarkMLl · 2021-03-31 20:22 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 05:02:20 pmCan I, confidently say, that LZ compression and dynamic Huffman are a tad interchangeable? Or are the principles behind each one very dissimilar? I think they're interchangeable, unless you work for Unisys. MarkMLl ---------------------------------------------------------------------- MarkMLl · 2021-03-31 20:24 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 05:21:23 pmBut, it's a one time thing, right, not the password you have to give every time a client comes round and ask for a bit of WiFi, right? You're not seriously suggesting that you extend your idea to QR codes giving the network name and password, are you? :-) MarkMLl ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 20:26 Hey Martin, I'll answer more thoroughly to your post, after I've had some sleep. I'm beginning to stare vaguely and drool... I hadn't think about what would be my max number of words. Your 10k to 20k is quite plausible and may hamper my effort a tad. I do think it's rather intriguing your 3 nibble solution. Quite a nice save. Well, Portuguese is a bit more rich in terms of the amount of day to day words. We're just that verbose. I'll have to do a comparison between both... If I can find a good source for a sample of Portuguese words... But in the mean time: Quote from: Martin_fr on March 31, 2021, 09:59:21 pmOf course, if you want to maximize the human-words efficiency, then you need to use a lookup table for decoding, as well as encoding. Because that is the only clash-free way. ARGH, me man, this is what I've been saying for all this time. Lookup table, binary tree with the lookup table, why wasn't I articulate enough to get the message through? And apart from that I can also be picky about the words if I find that I need to tweak them due to phonetic issues. Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 20:30 Hey Mark, Quote from: MarkMLl on March 31, 2021, 10:24:13 pmYou're not seriously suggesting that you extend your idea to QR codes giving the network name and password, are you? :-) That's a wonderful idea, I've never seen that. I should patent it. No of course not. That's utter crazy talk. No one would do that, right? ;-P Cheers, Gus ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-03-31 21:19 Hey Mark, Quote from: MarkMLl on March 31, 2021, 10:22:27 pmI think they're interchangeable, unless you work for Unisys. I know you should never explain a joke, but this one got way over my head. Qué? A bit of help here Cheers, Gus ---------------------------------------------------------------------- Martin_fr · 2021-03-31 22:00 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 10:26:48 pmQuote from: Martin_fr on March 31, 2021, 09:59:21 pmOf course, if you want to maximize the human-words efficiency, then you need to use a lookup table for decoding, as well as encoding. Because that is the only clash-free way. ARGH, me man, this is what I've been saying for all this time. Lookup table, binary tree with the lookup table, why wasn't I articulate enough to get the message through? And apart from that I can also be picky about the words if I find that I need to tweak them due to phonetic issues. The clashes just reduce the amount of use-able words. (as do phonetics, and words no one knows how to spell ). So for maximizing the data density, you want a table/tree. Encoding 12bits chunks may work with clashes (also probably not), but you may spent a lot of time to find a good calculation to reduce the number of clashes enough (that is once per language/dictionary). 9 or 10 bit chunks probably have enough human words, so a hash- algorithm can be found, only using hand picked words. To encode, you still use a list (the binary 16bit or 12bit data is a nice index). For decoding you can use a tree. Or a hash table, and then only resolve clashes via a tree (or even list) in the hash bucket.) Technically you can also do a binary search.... ---------------------------------------------------------------------- AlanTheBeast · 2021-03-31 22:33 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 10:11:32 pmHey AlanTheBeast, Quote from: AlanTheBeast on March 31, 2021, 09:42:39 pmEh?  W3W want to provide a simple word set to replace addresses ... esp. in locale's where there is no such things as an "address." as we generally use them. GPS is a GNSS (navigation satellite service).  Good luck replacing that with W3W. If you mean coordinates, W3W doesn't replace that either - it's just a different encoding of a coordinate. Well, I'll admit that replace is a bit strong. I should've added some air quotes there. Maybe the best analogy would be a translation service, more human readable. Akin to what DNS does for human readable domain names and IP addresses. If each domain name would be 3 human readable words and an IP address was a 3 meter by 3 meter square piece of the Earth's surface, right? Thanks for the nudge to correct myself Cheers, Gus Sorry about that - I get annoyed when people use "GPS" as a replacement for "coordinates".  I like the "W3W" concept.  I attempted[1] to send letters to my son while he was in Asia/Australia using it.  (Real address envelope and separate "W3W" version separate envelope).   None got through.  One was returned from Australia post however.... I suspect some of the post workers 'know' what it is but fear if they deliver one, then the precedent is set and they're not set up to routinely process such. [1]      Greg Beastson           Deadbeat Hostel           ///broke.outer.decay              /// = what three words           Australia ---------------------------------------------------------------------- lucamar · 2021-04-01 02:29 Quote from: Gustavo 'Gus' Carreno on March 31, 2021, 11:19:26 pmQuote from: MarkMLl on March 31, 2021, 10:22:27 pmI think they're interchangeable, unless you work for Unisys.I know you should never explain a joke, but this one got way over my head. Qué? A bit of help here Mark is probably referring to the Unisys patent over the GIF compression algorithm, which is a fairly standard LZW that most people thought was clearly a case of "previous art" and should never have been conceded. But then, the USA patent office is a world unto themselves ... one that apparently would give a patent for the wheel if anyone presented it now More info. ---------------------------------------------------------------------- MarkMLl · 2021-04-01 07:16 Quote from: lucamar on April 01, 2021, 04:29:23 amQuote from: Gustavo 'Gus' Carreno on March 31, 2021, 11:19:26 pmQuote from: MarkMLl on March 31, 2021, 10:22:27 pmI think they're interchangeable, unless you work for Unisys.I know you should never explain a joke, but this one got way over my head. Qué? A bit of help here Mark is probably referring to the Unisys patent over the GIF compression algorithm, which is a fairly standard LZW that most people thought was clearly a case of "previous art" and should never have been conceded. But then, the USA patent office is a world unto themselves ... one that apparently would give a patent for the wheel if anyone presented it now More info. I was, yes, but it was a complicated one. LZW compression was, arguably, novel, and the patents granted to Unisys and others for its invention were not, arguably, invalidated by prior art. Unarguably, Compuserve should not have chosen a patent-encumbered algorithm for something which they should have anticipated was going to be used heavily. The whole area of software patents is unarguably messy, with entirely reasonable claims at one end of the spectrum and "Illegal Numbers" (possession of which is a crime) at the other. Slap bang in the middle of that is the inventor of a particularly neat text comparison algorithm who as a result has become somewhat of a pariah, the algorithm can be found in the Meld utility but just about nowhere else. As some might remember, I had the displeasure of working for Burroughs which was one of the constituents of Unisys. They had what I considered to be a very unhealthy attitude: "Burroughs invented virtual memory... Burroughs invented the virtual machine... Burroughs invented the recursive descent compiler"... I made myself unpopular by suggesting that Burroughs also invented the intermittent fault, their "cost reduction department" was notorious. Unfortunately, it has become clear to me over the years that Burroughs does, in fact, have a good claim to having invented virtual memory etc. in workable form: it didn't, however, prevent the company from being a very unpleasant and unsuitable place for a young graduate. All of which has, obviously, flavoured my attitude towards Unisys's patchy enforcement of the LZW patent. MarkMLl