Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click to go to the Oscars.
Click to go to the Oscars.
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


Listing 4-4 is obviously the classic Hello World program in Java, although it seems not nearly as complex as the last example. Believe it or not, all four of these programs are the same, just viewed differently.

Listing 4-1 is pure hexadecimal and comes from the file HelloWorld.class. This is what you’d see by looking at the file with a disk editor such as Norton Disk Editor. Listing 4-5 is a simple application that you can use to read files as hexadecimal digits.

Listing 4-5 HexReader

   import java.awt.*;
   import java.io.*;

   public class HexReader extends Frame {

    TextArea output = new TextArea();
    Button OpenFile = new Button(“Open File”);

    public static void main (String[] args) {

     HexReader h = new HexReader();
     Toolkit t = Toolkit.getDefaultToolkit();
     Dimension d = t.getScreenSize();

     h.init();
     h.resize(d.width/2, d.height/2);
     h.move(d.width/4, d.height/4);
     h.show();

    }

    public HexReader() {

     super(“HexReader”);

    }

    public void init() {

     Panel p = new Panel();
     p.setLayout(new FlowLayout());
     p.add(OpenFile);
     add(“South”, p);
     add(“Center”, output);
    }

    public boolean action(Event e, Object what) {

     if (e.target == OpenFile) {
      File f = chooseFile();
      printFile(f);
      return true;
     }

     return false;

    }

    public File chooseFile() {

     FileDialog fd = new FileDialog(new Frame(),
     “Please choose a file:”, FileDialog.LOAD);
     fd.show();

     return new File(fd.getDirectory(), fd.getFile());

    }

    public void printFile(File f) {

     try {
      output.setText(“”);
      FileInputStream fin =  new FileInputStream(f);
      byte[] buffer = new byte[(int) f.length()];
      int bytesread = fin.read(buffer);
      output.setText(hexprint(buffer));
     }
     catch (Exception e) {
     }

    }

    public String hexprint(byte[] b) {

     StringBuffer sb = new StringBuffer(b.length * 2);
     for (int i = 0; i < b.length; i++) {
      sb.append(BitsToChar(b[i] >> 4));
      sb.append(BitsToChar(b[i] & 0x0000000F));
     }
     return sb.toString();
    }

    public char BitsToChar(int bits) {

     int j = bits & 0x0000000F;
     switch (j) {
      case 0: return ‘0’;
      case 1: return ‘1’;
      case 2: return ‘2’;
      case 3: return ‘3’;
      case 4: return ‘4’;
      case 5: return ‘5’;
      case 6: return ‘6’;
      case 7: return ‘7’;
      case 8: return ‘8’;
      case 9: return ‘9’;
      case 10: return ‘A’;
      case 11: return ‘B’;
      case 12: return ‘C’;
      case 13: return ‘D’;
      case 14: return ‘E’;
      case 15: return ‘F’;
      default:
       throw new IllegalArgumentException(j +
       “ is not a valid value for a hexadecimal digit.”);

     }

    }

   }

The main() method initializes the Frame shown in Figure 4-1. It has a TextArea field called output where the actual hex data appears and a single button with the label “Open File.” When the users click the Open File button, they see a file dialog box in which they can choose a file. The program passes the chosen file to the printFile() method. The printFile() method opens the file, connects an input stream to it so that the contents can be read, and reads the contents into a byte array called buffer. Then the buffer is passed to the hexprint() method to get a hexadecimal string that is displayed in the output TextArea.


Figure 4-1  The HexReader application.

Our main interest here is in the hexprint() method, so let’s take a closer look at it. The argument to hexprint() is a byte array, b. It returns a string that contains a hexadecimal printout of those bytes. Each byte in the array is read in order and converted to two hexadecimal digits.

To convert a byte to two hex digits, it is first split into its first four bits (b[i] >> 4) and its last four bits (b[i] & 0x0000000F). The result of each of these calculations is an int. This int is passed to BitsToChar(). BitsToChar() is little more than a switch statement that converts a single int between 0 and 15 to a hexadecimal digit between 0 and F. Numbers outside the acceptable range (greater than 15 or less than 0) cause a new IllegalArgumentException to be thrown. This is a RuntimeException, so you don’t need to catch or declare it. Each of the chars is appended to the temporary StringBuffer sb. Finally sb.toString() is returned.

A raw hex dump of a file is not very informative, although you can learn a little from it. All Java .class files should begin with the 4-byte magic number 0xCAFEBABE — that is -889,275,714 in decimal. If you don’t see this number at the beginning of the file, then you know it’s not a valid Java byte code file, even if the file name ends in .class.

Bytes four and five of a .class file (the two bytes immediately following CAFEBABE) show the minor version of the compiler that produced this file. The two bytes after that show the major version of the compiler. In this example, the minor version is 0x0003 (3), and the major version is 0x002D j(45). When a Java virtual machine reads a .class file, it checks to see if it understands that version of the format. A virtual machine can generally read all of the minor versions in a major version, but if the major version changes, a new virtual machine is required. Some virtual machines may also understand older major versions, but they should not attempt to read files with newer major versions. The .class file format is actually more stable than the language and the API. Both Java 1.0.2 and Java 1.1 use the 45.3 .class file format.

The remaining digits all have meanings, but pulling them out by hand is excruciatingly painful. In fact, even in total disaster situations (such as when your hard disk has crashed, taking with it three months of un-backed-up, mission-critical .class files while the corresponding .java files are completely lost), you would probably copy the byte codes out of the file by hand and manually enter them into another computer where you could decompile them.


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.