Title BINHEX - File Translator Keywords ASCII, Hexadecimal, Bitnet Computer IBM PC/XT/AT Operating System MS-DOS Programming Language Turbo Pascal v. 5.0 Hardware Needed IBM PC/XT/AT Author H.O. Colijn Correspondence Addr. Ohio State University, Central Electron Optics Facility 042 Fontana Labs 116 W. 19th Ave. Columbus, OH 43210-1110 (614)292-0674 Abstract: Some computer networks (such as Bitnet) can transmit ASCII files only. Others (such as Internet) require a special facility (i.e. ftp) to transmit binary files, whereas ASCII files can be transmitted easily using the MAIL facilities. While this allows source code to be trans- mitted easily, it is difficult to send executable programs, spectral data files, or archived files. Many word processing programs also use non-ASCII characters to store document formatting information. It is difficult for people to exchange information in the format they desire over computer networks. This program will convert a binary file to and from the hexadecimal equivalents of the binary bytes. That is, each byte in the binary file will be converted into 2 ASCII characters (0-9,A-F) corresponding to the value of the high and low four bits (respectively) of the binary value. Thus, regardless of the contents of the original file, the resulting file is strictly ASCII. Note that this translation doubles the original size of the file since each byte of the binary file is converted into 2 ASCII characters, each requiring one byte.  Title BINHEX - File Translator Keywords ASCII, Hexadecimal, Bitnet Computer IBM PC/XT/AT Operating System MS-DOS Programming Language Turbo Pascal v. 5.0 Hardware Needed IBM PC/XT/AT Author H.O. Colijn Correspondence Addr. Ohio State University, Central Electron Optics Facility 042 Fontana Labs 116 W. 19th Ave. Columbus, OH 43210-1110 (614)292-0674 Abstract: Some computer networks (such as Bitnet) can transmit ASCII files only. Others (such as Internet) require a special facility (i.e. ftp) to transmit binary files, whereas ASCII files can be transmitted easily using the MAIL facilities. While this allows source code to be trans- mitted easily, it is difficult to send executable programs, spectral data files, or archived files. Many word processing programs also use non-ASCII characters to store document formatting information. It is difficult for people to exchange information in the format they desire over computer networks. This program will convert a binary file to and from the hexadecimal equivalents of the binary bytes. That is, each byte in the binary file will be converted into 2 ASCII characters (0-9,A-F) corresponding to the value of the high and low four bits (respectively) of the binary value. Thus, regardless of the contents of the original file, the resulting file is strictly ASCII. Note that this translation doubles the original size of the file since each byte of the binary file is converted into 2 ASCII characters, each requiring one byte. BINHEX.DOC 2 How to use the program. I have tried to keep operation of the program as simple as possi- ble and have also tried to catch all the possible errors I could think of. DEFINITIONS ASCII -- An acronym for "American Standard Code for Information Interchange". These codes include uppercase and lowercase alpha- numeric characters and various control codes. It is generally considered the "least common denominator" for exchanging informa- tion between computers. bytes -- A byte is eight binary digits (ones or zeros). In ASCII text, a character requires 1 byte of storage. binary file -- I am using the term "binary file" to refer to any file that is not in HEX format. It could already be in ASCII format, it could be an EDS spectrum, it could be an executable program, it could be a word processing file, etc. checksum -- A checksum is a method of verifying error free trans- mission of data. One simply adds the numeric values of all the characters that are in a file to obtain the checksum. After the file has been transmitted, the checksum is recalculated and checked against the original checksum. If the two sums are not the same, we assume there was an error in transmission. -- This symbol means to press the "Enter" or "Return" key. extension -- In MS-DOS or PC-DOS, disk files can have names consisting of eight characters, a period, and a 3 character extension. The extension is the part of the name following the period. HEX -- Short for "hexadecimal". The hex system is a base 16 number system with the numbers 10-15(decimal) represented by the alphabetic characters A-F. Each hexadecimal number can be ex- pressed as 4 binary digits; thus there are two hexadecimal digits per byte of information. In this program, the "HEX" format indi- cates that the hexadecimal numbers are represented by the ASCII characters 0-9,A-F. STARTING THE PROGRAM At your DOS prompt type: binhex The program will then prompt you to enter a filename to be trans- lated. BINHEX.DOC 3 COMMAND LINE OPTION If you wish, you may give the filename on the command line rather than answering the question from within the program. For exam- ple, instead of invoking the program as: BINHEX you would invoke it as (for example...): BINHEX BINFILE.EXE or BINHEX A:BINFILE.EXE or BINHEX C:\BIN\BINFILE.EXE etc. The program will then skip the section asking you for the file- name. FILENAMES You may use either upper or lower case letters. If the file you wish to convert is located in a different subdi- rectory (or disk drive), you will have to provide the complete path and drive information so that the program can find your file. The program will put the converted (HEX) file in the same subdirectory it found the binary file. When converting from HEX back into binary, the program will put the binary file into the current subdirectory. The path information of the original program is lost when converting it from HEX back into binary. Since the major application of the program will be to transfer files from one computer to another, it is likely that the direc- tory structure on the target computer will not be the same as the directory structure on the source computer. For this reason, I strip off the path information before storing the filename in the HEX file. The program assumes that a filename with anything other than an extension of .HEX is a binary file and is to be converted to HEX format. A filename with no extension at all (e.g. FILENAME. ) is considered to be a binary file. If the filename ends with an extension of .HEX the program as- sumes that the file is already in HEX format and you wish to convert it back to binary. You are given a chance to quit before the translation takes place. The program will overwrite any other programs in the subdirectory with the same name. When converting from HEX back into binary, the program will warn you if it finds a file which will be overwritten. BINHEX.DOC 4 OPERATION Sample sessions are recorded in the appendices. Before the program actually begins the translation you will be given a chance to quit or abort the session. If you just type a instead of a filename, the program will stop. After you have entered the filename, the program will pause to confirm the translation you have chosen. If you wish to quit at that time, just type "N". In the prompts, the symbol "" indicates that the default answer is "YES". Pressing the "Enter" or "Return" key at this point indicates an affirmative answer and the program will con- tinue operation. Because the program is not very fast, it provides a status report of what is happening. During the actual translation it prints a dot for each 1K of original file that has been converted. The program calculates a checksum when translating the file from binary into HEX and stores it in the HEX file. When translating the file from HEX back into binary, the program will compare the checksum of the binary file with the checksum stored in the HEX file. If the two checksums differ, the program will display a message. You should assume that there was an error in the trans- mission of the file and repeat the transmission. NOTES This program was compiled under Turbo Pascal version 5.0. Al- though I haven't tried it, I believe that it should also compile under Turbo Pascal version 4.0. If you cannot compile the pro- gram yourself, contact me at the above address. Please enclose a blank formatted IBM disk. Suggestions and comments are welcome. DISCLAIMER - Although I believe the program to be working proper- ly, neither I nor The Ohio State University can accept any re- sponsibility for its operation. It is your responsibility to verify that the program is working properly for your purposes. BINHEX.DOC 5 APPENDICES SAMPLE 1 -- BINARY TO HEX CONVERSION Enter the name of the file to be converted. Be sure to include the extension and the path if needed. (e.g. \bin\binhex.exe) The HEX file will have the same name as the binary file except with a .HEX extension The binary file will be reconstructed with the original name. To quit or abort, hit the key only. --> \bin\binhex.exe <-- enter your filename here ---------------------------------------------------------------- Filename: binhex.exe I will proceed with Binary --> HEX conversion. OK? ^ Calculating Checksum... (| enter a ) Translating file, "binhex.exe" into HEX format. ............ All done. BINHEX.DOC 6 SAMPLE 2 -- HEX TO BINARY CONVERSION Enter the name of the file to be converted. Be sure to include the extension and the path if needed. (e.g. \bin\binhex.exe) The HEX file will have the same name as the binary file except with a .HEX extension The binary file will be reconstructed with the original name. To quit or abort, hit the key only. --> binhex.hex ---------------------------------------------------------------- binhex.exe already exists in this subdirectory. It will be overwritten if you proceed with the translation. I will proceed with converting "binhex.hex" --> "binhex.exe" OK? ........................ ^ (enter a here |) ---------------------------------------------------------------- File "binhex.exe" converted successfully. (If successful conversion) ---------------------------------------------------------------- File "binhex.exe" has checksum error. This file may have been corrupted during transmission. (If bad transmission)  Title BINHEX - File Translator Keywords ASCII, Hexadecimal, Bitnet Computer IBM PC/XT/AT Operating System MS-DOS Programming Language Turbo Pascal v. 5.0 Hardware Needed IBM PC/XT/AT Author H.O. Colijn Correspondence Addr. Ohio State University, Central Electron Optics Facility 042 Fontana Labs 116 W. 19th Ave. Columbus, OH 43210-1110 (614)292-0674 PROGRAM BinHex; USES Dos, Crt; TYPE LongNameString = string[80]; NameString = string[20]; VAR InputFilename : LongNameString; BinaryFlag,FileConversionError : boolean; {****************************************} FUNCTION IsFilePresent(filename:longnamestring):boolean; VAR test : file of byte; BEGIN Assign(test, filename); {$I-} Reset(test) {$I+}; IF ioresult <> 0 THEN IsFilePresent := false ELSE IsFilePresent := true; END; {****************************************} {****************************************} FUNCTION IsFileBinary (filename:longnamestring):boolean; VAR extension : string[4]; i,DotPosition : byte; BEGIN DotPosition := pos('.', filename); {check for filename extension} IF DotPosition = 0 THEN {if dot not found} IsFileBinary := true ELSE BEGIN extension := copy(filename,DotPosition,4); FOR i := 1 to length(extension) DO extension[i] := upcase(extension[i]); IF extension = '.HEX' THEN IsFileBinary := false ELSE IsFileBinary := true; END; END; {****************************************} {****************************************} PROCEDURE OpeningScreen; BEGIN ClrScr; Writeln; GotoXY (15,5); Writeln('Binary and HEX character file translator'); GotoXY (15,7); Writeln(' H. Colijn'); GotoXY (15,8); Writeln(' Ohio State University'); GotoXY (15,9); Writeln(' Central Electron Optics Facility'); GotoXY (15,11); Writeln(' version 1.1'); Delay(2000); END; {****************************************} {****************************************} Procedure CannotFind(Filename : longnamestring); BEGIN IF (filename='?') THEN EXIT; ClrScr; Writeln(^G); GotoXY(5,10); Writeln ('Can''t find ',Filename); Delay(2000); END; {****************************************} {****************************************} PROCEDURE HelpScreen; VAR answer : char; BEGIN ClrScr; Writeln('This program will convert binary files into a HEX format suitable for sending '); Writeln('via EMAIL. Note that this HEX format is probably not compatible with other '); Writeln('HEX formats which may be available. '); Writeln; Writeln('The program assumes that unless the file has an extension of ".HEX", it is a '); Writeln('binary file. For the purposes of this program, a binary file is any file that '); Writeln('is not in the HEX format. It could well be a text file or a file generated by '); Writeln('your word processor. '); Writeln; Writeln('Be sure to allow sufficient room for the translated file on your disk. The '); Writeln('HEX file will be twice the size of the original file. '); Writeln; Writeln('Entering a filename:'); Writeln; Writeln(' b:\program.exe (convert program.exe on drive B: to HEX format)'); Writeln(' \path1\path2\spectra.arc (your path specification can be quite long)'); Writeln(' article (convert file "article" to HEX format, note that a '); Writeln(' file with no extension is considered "binary")'); Writeln(' \temp.hex (convert HEX file back to binary format)'); Writeln; Writeln('The program will also accept a filename on the command line.'); Writeln(' e.g. binhex \data\test.arc'); Writeln; Writeln('Hit any key to continue.'); answer := ReadKey; END; {****************************************} {****************************************} PROCEDURE StripPath(InputString : LongNameString; VAR OutputString : NameString); {We cannot assume that the target computer will have the same path structure as the original computer. Since the input filename string may contain path information, we will want to strip both the drive and path information from the string before storing the filename in the .HEX file.} VAR ColonPosition, BackSlashPosition : byte; BEGIN OutputString := InputString; ColonPosition := pos(':',InputString); {check if disk drive specified} IF ColonPosition <> 0 THEN delete(OutputString,1,ColonPosition); {delete drive info} BackSlashPosition := pos('\',OutputString); {find location of \} WHILE BackSlashPosition <>0 DO BEGIN delete(OutputString,1,BackSlashPosition); {delete up thorough \} BackSlashPosition := pos('\',OutputString); END; END; {****************************************} {****************************************} PROCEDURE BinHexConversion(BinaryFilename:longnamestring); VAR i,BinaryFileSize,HexChecksum : longint; BinaryByte, DotPosition : byte; HiOrderCharacter,LoOrderCharacter : char; EmbeddedFilename : NameString; HexFilename : LongNameString; HexFile : text; BinaryFile : file of byte; answer : string; BEGIN ClrScr; BEGIN Writeln('Filename: ',BinaryFilename); Writeln; Write('I will proceed with Binary --> HEX conversion. OK? '); Readln(answer); IF NOT((upcase(answer[1])='Y') or (answer='')) THEN Exit; END; Assign(BinaryFile,BinaryFilename); Reset(BinaryFile); BinaryFilesize := filesize(BinaryFile); DotPosition := pos('.', BinaryFilename); {check for filename extension} IF DotPosition = 0 THEN {if dot not found} HexFilename := BinaryFilename + '.HEX' ELSE BEGIN HexFilename := BinaryFilename; Delete(HexFilename,DotPosition,4); {if extension found, delete it} Insert('.HEX', HexFilename, DotPosition); {append .HEX} END; HexChecksum := 0; {calculate checksum for} Reset(BinaryFile); {verifying error-free transmission} Writeln; Writeln('Calculating Checksum...'); FOR i := 1 to BinaryFilesize DO BEGIN {this loop performs the checksum} Read (BinaryFile,BinaryByte); HexChecksum := (HexChecksum + BinaryByte) mod $8000; {use modulo arithmetic} END; {to avoid overflows} StripPath(BinaryFilename,EmbeddedFilename); {path info not needed on new pc} Assign (HexFile, HexFilename); Rewrite(HexFile); Writeln(Hexfile,EmbeddedFilename); {embed the binary filename and checksum} Writeln(Hexfile,HexChecksum); {in the .HEX file for later unpacking} Writeln; Writeln('Translating file, "',BinaryFilename,'" into HEX format.'); Reset(BinaryFile); FOR i := 1 to BinaryFilesize DO BEGIN {this loop performs the conversion} Read (BinaryFile,BinaryByte); HiOrderCharacter := chr(($F0 AND BinaryByte)shr 4 + $30); LoOrderCharacter := chr($0F AND BinaryByte + $30); IF HiOrderCharacter > '9' THEN {for hex digits A..F} HiOrderCharacter := chr(ord(HiOrderCharacter) + $07); IF LoOrderCharacter > '9' THEN LoOrderCharacter := chr(ord(LoOrderCharacter) + $07); Write (HexFile,HiOrderCharacter); Write (HexFile,LoOrderCharacter); IF (i mod $400)=0 THEN Write ('.'); END; Close (HexFile); Close (BinaryFile); Writeln; Writeln; Writeln('All done.'); END; {****************************************} {****************************************} PROCEDURE HexBinConversion(HexFilename: longnamestring); VAR BinaryFilename : namestring; HiOrderCharacter,LoOrderCharacter : char; BinaryByte,HiNibble, LoNibble: byte; i, BinaryChecksum, HexChecksum : longint; HexFile : text; BinaryFile : file of byte; answer : string; BEGIN ClrScr; Assign(Hexfile,HexFilename); Reset(HexFile); Readln (Hexfile, BinaryFilename); BEGIN IF (IsFilePresent(BinaryFilename)) THEN BEGIN Writeln(BinaryFilename,' already exists in this subdirectory.'); Writeln('It will be overwritten if you proceed with the translation.'); Writeln; END; Write ('I will proceed with converting "',HexFilename,'" --> "',BinaryFilename,'" OK? '); Readln(answer); IF NOT((upcase(answer[1])='Y') or (length(answer)=0)) THEN exit; END; Assign (BinaryFile, BinaryFilename); Rewrite (BinaryFile); Readln (Hexfile, HexChecksum); BinaryChecksum := 0; i := 0; WHILE not EOF(hexfile) DO BEGIN {this loop performs the conversion} Read (HexFile,HiOrderCharacter ); Read (HexFile,LoOrderCharacter ); HiNibble := ord(HiOrderCharacter) - $30; LoNibble := ord(LoOrderCharacter) - $30; IF HiNibble > $0F THEN {for hex digits A..F} HiNibble := HiNibble - $07; IF LoNibble > $0F THEN {for hex digits A..F} LoNibble := LoNibble - $07; BinaryByte := (HiNibble shl 4) + LoNibble; Write (BinaryFile,BinaryByte); BinaryChecksum := (BinaryChecksum + BinaryByte) mod $8000; i := i+1; IF (i mod $400)=0 THEN Write ('.'); END; Close (BinaryFile); Close (HexFile); ClrScr; IF HexChecksum <> BinaryChecksum THEN BEGIN Writeln (^G); GotoXY (10,5); Writeln ('File "',BinaryFilename,'" has checksum error.'); GotoXY (10,7); Writeln ('This file may have been corrupted during transmission.'); END ELSE BEGIN GotoXY (10,5); Writeln ('File "',BinaryFilename,'" converted successfully.'); END; END; {****************************************} {****************************************} PROCEDURE GetFilename(VAR Filename : LongNameString); VAR inputfile : file of byte; BEGIN {GetFilename} ClrScr; Writeln; Writeln; Writeln('Enter the name of the file to be converted. '); Writeln('Be sure to include the extension and the path if needed.'); Writeln('(e.g. \bin\binhex.exe) '); Writeln; Writeln ('The HEX file will have the same name as the binary file'); Writeln ('except with a .HEX extension'); Writeln; Writeln ('The binary file will be reconstructed with the original name.'); Writeln; Writeln ('To quit or abort, hit the key only.'); Writeln; Write('--> '); {$I-} Readln(Filename); {$I+} IF (Filename = '') THEN {user wants to quit} HALT; IF InputFilename = '?' THEN {user wants help} HelpScreen; END; {GetFilename} {****************************************} BEGIN {main} OpeningScreen; IF Paramcount <> 0 THEN {is filename on command line?} InputFilename := ParamStr(1) ELSE GetFilename(InputFilename); WHILE NOT(IsFilePresent(InputFilename)) DO BEGIN CannotFind(InputFilename); GetFilename(InputFilename); END; IF IsFileBinary(InputFilename) THEN BinHexConversion(InputFilename) ELSE HexBinConversion(InputFilename); END. {main}