[comp.sys.mac.misc] Responses to BinHex 4.0 ques

jfs@genrad.com (John F. Spooner) (08/21/90)

I have recieved a few e-mail requests to forward any information I had recieved
about BinHex.  The reason I wanted e-mail was to prevent excess traffic in the
newsgroup.  I now see there is room for discussion.  So if anyone has any info
(manual, hints, ...)on BinHex 4.0, I ask that you please post them here.

woofy@sgi.com (Wolfchild=) (08/24/90)

In article <38442@genrad.UUCP> jfs@genrad.UUCP (John F. Spooner) writes:
>I have recieved a few e-mail requests to forward any information I had recieved
>about BinHex.  The reason I wanted e-mail was to prevent excess traffic in the
>newsgroup.  I now see there is room for discussion.  So if anyone has any info
>(manual, hints, ...)on BinHex 4.0, I ask that you please post them here.

I've been trying to to cobble together a deBinHexing application all
summer, and here's the info that I've been able to come up with (this file
runs upwards of 150 lines, so hit 'n' if you're not interested):

A extremely nice fellow named John Rawnsley in the UK sent me Email (E for
Enlightenment) describing the BinHex encoding algorithm.  First each byte
is converted into a bit stream which is chopped into 6 bit chunks.  Each of
these chunks are then mapped through the 'magic string'-each 6 bits
represent a number n, and map to the nth character in the 'magic
string' (! is the 0th place, and r is the 63rd):

!"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr

So for an encoded file called 'Cosmic Wimpout', the first few bytes of the
BinHex encoded file (after the colon) would go something like this:
                                                   
00001110  01000011  01101111
<Length>   C         o
 
becomes

000011  100100  001101  101111
  (3)    (36)    (13)    (47)

which maps through the 'magic string' to

   $       N       0       [

The BinHex encoded portion of a text file are bracketed by colons (:).
Before the first colon there is this line of text:

(This file must be converted with BinHex 4.0)

So the beginning of the 'Cosmic Wimpout.hqx' file would look like this:

(This file must be converted with BinHex 4.0)
:$N0[

Here is the general format of a BinHex encoded file:


     1       n       4    4    2    4    4   2  (length)
    +-+---------+-+----+----+----+----+----+--+
    |n| name... |0|TYPE|AUTH|FLAG|DLEN|RLEN|HC| (contents)
    +-+---------+-+----+----+----+----+----+--+

            DLEN                             2  (length)
    +--------------------------------------+--+
    |   DATA FORK                          |DC| (contents)
    +--------------------------------------+--+

            RLEN                             2  (length)
    +--------------------------------------+--+
    |   RESOURCE FORK                      |RC| (contents)
    +--------------------------------------+--+


The first byte is a length byte for the original filename.  Then comes the
name and a null.  Following that are the Finder type, creator, the length
of the data fork, the length of the resource fork, and the CRC for the
header. Finally come the data fork and its CRC, and the resource fork and
its CRC.

I'm not quite sure how to calculate the CRC values.  I'm led to understand
that it's a MacBinary II style CRC, but I've found no description of it.
I'm writing my application in Pascal, but I've found this snippet of C
source code to work from:

/* An array useful for CRC calculations that use 0x1021 as the "seed" */
word magic[] = {
    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
    };


/*
 * calc_crc() --
 *   Compute the MacBinary II-style CRC for the data pointed to by p, with the
 *   crc seeded to seed.
 *
 *   Modified by Jim Van Verth to use the magic array for efficiency.
 */

short calc_mb_crc(p, len, seed)
unsigned char *p;
long len;
short seed;
{
  short hold;      /* crc computed so far */
  long  i;         /* index into data */

  extern unsigned short magic[];   /* the magic array */

  hold = seed;     /* start with seed */
  for (i = 0; i < len; i++, p++) {
    hold ^= (*p << 8);
    hold = (hold << 8) ^ magic[(unsigned char)(hold >> 8)];
  }

  return (hold); } /* calc_crc() */


I've also heard talk of some run length encoding.  The following is an
excerpt from a text file that's floating around on sumex:

---
There is some run length encoding, where the character to be repeated is
followed by a 0x90 byte then the repeat count.  For example, ff9004 means
repeat 0xff 4 times.  The special case of a repeat count of zero means it's
not a run, but a literal 0x90.  2b9000 => 2b90.

*** Note: the 9000 can be followed by a run, which means to repeat the 0x90
(not the character previous to that).  That is, 2090009003 means a 0x20
followed by 3 0x90's.
---

I would welcome email discussion from anyone who has or wants more info.

Thanks

-------------------------------------------------------------------------------
Andy Fabans

   /\ /\        woofy%yorgi@csd.sgi.com (Wolfchild)
    o o                             
    \ /     "The subliminal argument has no basis in fact.  It is simply a
     *       vehicle to pursue a case otherwise marred by the First Amendment."
                                     - Suellen Fulstone
                                          Attorney representing Judas Priest
-------------------------------------------------------------------------------

esmith@goofy.apple.com (Eric Smith) (08/30/90)

I've got some C code that decodes BinHex 4.0 format.  I tried to send you
mail, but both of these addresses bounce:

   woofy@sgi.com
   woofy%yorgi@csd.sgi.com

How about sending me a valid address?

--
Eric L. Smith      Opinions expressed herein do not necessarily reflect those
esmith@apple.com   of my employer, friends, family, computer, or even me!  :-)