Create MD5 Hash for File in PeopleCode - Example

In this tutorial, we will explain how to create a MD5 hash / Checksum for a file in PeopleSoft, with a PeopleCode example.  We will utilise java.security.MessageDigest to generate the MD5 hash. You can easily stick this code to an Application Engine program or even a record field event, depending on your requirements. The high level steps involved in creating a MD5 hash are captured below:

Steps to Create a MD5 Hash / Checksum for a file in PeopleCode
Steps to Create a MD5 Hash / Checksum for a file in PeopleCode


We will take you through all these steps now with PeopleCode snippets.


1. Read Input File


In this step, we will read the input file for which you have to generate a MD5 hash, as an object of type java.io.FileInputStream in PeopleCode. You have to pass the file name as a parameter to this call as shown below:

/* Create an InputStream object for the file first */
Local JavaObject &InputMD5Reader = CreateJavaObject("java.io.FileInputStream", "c:\temp\TESTER.zip");


2. Create Message Digest Object


To get an object of type java.security.MessageDigest, you have to invoke the getInstance static method and pass “MD5” as the hash type to this method. We use GetJavaClass PeopleCode method for this purpose, and the code to get a MessageDigest object is shown below:

/* Get a Message Digest Object */
Local JavaObject &messageDigest = GetJavaClass("java.security.MessageDigest").getInstance("MD5");


3. Read Bytes from File


To generate an MD5 hash, it is required to read all the bytes from a File into a Java Array recursively, and pass the bytes that are read to a function that can generate the digest. We will use the code snippet below to read the input file byte by byte in PeopleCode.

/* Create Java Array to assist in Hashing */
Local JavaObject &ByteBufferArray = CreateJavaArray("byte[]", 1024);
/* Read Input File Byte by Byte */
Local number &NumberOfBytes = &InputMD5Reader.read(&ByteBufferArray);
While &NumberOfBytes > 0   
   &NumberOfBytes = &InputMD5Reader.read(&ByteBufferArray);
End-While;


4. Update Message Digest Object


For every set of bytes that is read, we invoke the update method in MessageDigest class, by passing the byte array, offset and number of bytes read. This method updates the digest using the specified array of bytes, by starting at the offset. The signature of this method is shown below:

Signature of update method in MessageDigest Class
Signature of update method in MessageDigest Class
The Peoplecode to invoke this method is shown below:

   &messageDigest.update(&ByteBufferArray, 0, &NumberOfBytes);


5.Get MD5 Checksum As Byte Array


When you pass all the bytes to the update method, the digest gets updated iteratively. Now, we have to get the calculated MD5 digest back in a byte array. To do this, we invoke the digest method in MessageDigest class. This method completes the hash computation by performing final operations  like padding etc. PeopleCode snippet is shown below

/* Get the calculated digest back */
Local JavaObject &bytearray = &messageDigest.digest();


6.Encode MD5 Hash as Hex String


Now that you have got the byte array in PeopleCode, you can encode this to a Hex string to create the MD5 hash. You can use any preferred approach of yours to create the hex string. The easiest one is to use the Hex class defined in org.apache.commons.codec.binary.Hex and invoke the encodeHexString method by passing the byte array you got in step 5. This returns a MD5 string back directly. But to use this, you need to load the JAR file commons-codec-1.4.jar (or equivalent, depending on your Java version) defined by Apache Commons Codec library. You can alternatively use native Java components, but you may have to use reflection based approaches for this. I leave the choice to you.

Local string &encodehex = GetJavaClass("org.apache.commons.codec.binary.Hex").encodeHexString(&bytearray);

You can use the returned MD5 hash string inside your program suitably. You can even wrap this as a PeopleCode function by passing the file name and returning a string back


Create MD5 Checksum For File – Complete PeopleCode Program


The complete PeopleCode program to generate MD5 checksum for a file is shown below

/* Calculate MD5 Checksum for a file in PeopleCode */
/* Create an InputStream object for the file first */
Local JavaObject &InputMD5Reader = CreateJavaObject("java.io.FileInputStream", "c:\temp\TESTER.zip");
/* Get a Message Digest Object */
Local JavaObject &messageDigest = GetJavaClass("java.security.MessageDigest").getInstance("MD5");
/* Create Java Array to assist in Hashing */
Local JavaObject &ByteBufferArray = CreateJavaArray("byte[]", 1024);
/* Read Input File Byte by Byte */
Local number &NumberOfBytes = &InputMD5Reader.read(&ByteBufferArray);
While &NumberOfBytes > 0   
   &messageDigest.update(&ByteBufferArray, 0, &NumberOfBytes);
   &NumberOfBytes = &InputMD5Reader.read(&ByteBufferArray);
End-While;
/* Get the calculated digest back */
Local JavaObject &bytearray = &messageDigest.digest();
/* Get MD5 hash as string */
Local string &encodehex = GetJavaClass("org.apache.commons.codec.binary.Hex").encodeHexString(&bytearray);

That completes our tutorial to generate MD5 hash / checksum for a File in PeopleSoft using PeopleCode. You can use this example in your code segment, and post a comment for any clarifications. 

3 comments:

  1. I tired to use following code in my Record.FieldChange PeopleCode. It returns an error "Object of class java.security.MessageDigest cannot be serialized". Does anyone have a clue how to handle it?

    Local JavaObject &messageDigest = GetJavaClass("java.security.MessageDigest").getInstance("MD5");

    ReplyDelete
  2. @Lily, did you made sure you had the right files in your classpath?

    ReplyDelete
  3. Same issue with me too. It returns an error "Object of class java.security.MessageDigest cannot be serialized". Does anyone have a clue how to handle it?

    Local JavaObject &messageDigest = GetJavaClass("java.security.MessageDigest").getInstance("MD5");

    ReplyDelete