Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In C or Java In this assignment you\'ll write a program that calculates the chec

ID: 3912143 • Letter: I

Question

In C or Java

In this assignment you'll write a program that calculates the checksum for the text in a file. Your program will take two command line parameters. The first parameter will be the name of the input file for calculating the checksum. The second parameter will be for the size of the checksum (8, 16 Command Line Parameters 1. 2. Your program must compile and run from the command line. The program executable must be named "checksum" (all lower case, no spaces or file extension) 3. nput the required file names as command line parameters. Your program may NOT prompt the user to enter the file names. The first parameter must be the name of the file used for calculating the checksum, as described below. The second parameter must be the size, in bits, of the checksum. The sample run command near the end of this document contains an example of how the parameters will be entered Your program should open the two files, echo the processed input to the screen, make the necessary calculations, and then output the ciphertext to the console (terminal) screen in the format described below. 4. Checksum size The checksum size is a single integer, passed as the first command line argument. The valid values are the size of the checksum, which can be elther 8, 16, or 32 bits. Therefore, if the first parameter is not one of the valid values, the program should advise the user that the value is incorrect with a message formatted as shown below: printf "Valid checksum sizes are 8, 16, or 32ln):; The message should be sent to STDERR. Format of the input file The input file will consist of the valid ASCII characters associated with the average text file. This includes punctuation, numbers, special characters, and whitespace.

Explanation / Answer

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;


public class checksum {

    public static void main(String[] args) {
        int checkSumSize = 0, characterCount = 0, checkSumResult = 0;
        String input = null;
        byte[] fileBytes;

        if (args.length < 2 || !Character.isDigit(args[1].charAt(0)) || !validBitSize(Integer.parseInt(args[1]))) {
            if (!Character.isDigit(args[1].charAt(0)) || !validBitSize(Integer.parseInt(args[1])))
                System.err.print(" Valid checksum sizes are 8, 16, or 32 ");
            else
                System.err.println(" Please provide the proper parameters. " +
                        "First Parameter is the input file name, second is the size of the checksum. ");
            System.exit(1);
        }

        try {
            input = readFileAsString(args[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (input != null){
            switch (Integer.parseInt(args[1])) {
                case 8:
                    checkSumSize = 8;
                    fileBytes = getAdjustedByteArray(input, checkSumSize);
                    characterCount = fileBytes.length;
                    checkSumResult = checksum8(fileBytes);
                    break;
                case 16:
                    checkSumSize = 16;
                    fileBytes = getAdjustedByteArray(input, checkSumSize);
                    characterCount = fileBytes.length;
                    checkSumResult = checksum16(fileBytes);
                    break;
                case 32:
                    checkSumSize = 32;
                    fileBytes = getAdjustedByteArray(input, checkSumSize);
                    characterCount = fileBytes.length;
                    checkSumResult = checksum32(fileBytes);
                    break;
                default:
                    System.err.print("Valid checksum sizes are 8, 16, or 32 ");
                    System.exit(1);
                    break;
            }
            System.out.printf(" %s %2d bit checksum is %8x for all %4d chars ",
                    formattedStringOutput(getAdjustedString(input, checkSumSize)), checkSumSize, checkSumResult, characterCount);
        }
    }

    // Checksum 8-Bit

    private static int checksum8(byte[] data) {
        int check = 0;

        for (byte b : data)
            check += b;

        return check & 0xFF;
    }

    // Checksum 16-bit

    private static int checksum16(byte[] data) {
        int check = 0;

        for (int i = 0; i <= data.length - 2; i += 2)
            check += ((data[i] << 8) | (data[i + 1] & 0xFF));

        return check & 0xFFFF;
    }

    // Checksum 32-bit
  
    private static int checksum32(byte[] data) {
        int check = 0;

        for (int i = 0; i < data.length; i += 4)
            check += ((data[i] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) | (data[i + 3])) & 0xffffffffL;

        return check;
    }

  
    private static String readFileAsString(String fileName) throws Exception {
        String data;
        data = new String(Files.readAllBytes(Paths.get(fileName)));
        return data;
    }


    private static String formattedStringOutput(String output) {
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < output.length(); i++) {
            if (i > 0 && i % 80 == 0)
                res.append(" ");
            res.append(output.charAt(i));
        }
        return res.toString();
    }


    private static byte[] getAdjustedByteArray(String in, int bit) {
        int originalSize = in.getBytes().length, newSize;

        newSize = originalSize + getPadding(originalSize, bit);
        byte[] temp = new byte[newSize];

        for (int i = 0; i < originalSize; i++) {
            temp[i] = (byte) in.charAt(i);
        }

        if (getPadding(originalSize, bit) > 0) {
            for (int j = originalSize; j < newSize; j++) {
                temp[j] = 88;
            }
        }
        return temp;
    }


    private static String getAdjustedString(String in, int bit) {
        int originalSize = in.getBytes().length, newSize;
        StringBuilder builder = new StringBuilder();
        newSize = originalSize + getPadding(originalSize, bit);

        for (int i = 0; i < originalSize; i++) {
            builder.append(in.charAt(i));
        }

        if (getPadding(originalSize, bit) > 0) {
            for (int j = originalSize; j < newSize; j++) {
                builder.append("X");
            }
        }

        return builder.toString();
    }


    private static boolean validBitSize(int bit) {
        int[] validBits = {8, 16, 32};
        return Arrays.stream(validBits).anyMatch(i -> i == bit);
    }

  
    private static int getPadding(int lengthOriginal, int bit) {
        int a = lengthOriginal;
        int b = bit == 32 ? 4 : 2;
        int c = 0;
        while (a % b != 0) {
            a = a + 1;
            c++;
        }
        return bit > 8 ? c : 0;
    }

}