Files
uni/second/semester1/CT255/Assessment/CT255-Assignment-1/submission/CT255_HashFunction1.java
2023-12-07 01:19:12 +00:00

98 lines
4.4 KiB
Java

//package ct255;
import java.util.Random;
public class CT255_HashFunction1 {
public static void main(String[] args) {
int res = 0;
if (args != null && args.length > 0) { // Check for <input> value
res = hashF1(args[0]); // call hash function with <input>
if (res < 0) { // Error
System.out.println("Error: <input> must be 1 to 64 characters long.");
}
else {
System.out.println("input = " + args[0] + " : Hash = " + res);
System.out.println("Start searching for collisions");
int collisionCount = 0; // variable to count the number of collisions found
// string containing all possible ASCII characters (exclusding control characters such as [NULL])
String allChars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
for (int i = 0; i < 100000; i++) { // checking one million randomly generated strings for hash collisions
StringBuilder str = new StringBuilder(); // creating a new StringBuilder to build char by char
// generating 64 random characters & appending them to str
for (int j = 0; j < 64; j++) {
char c = allChars.charAt(new Random().nextInt(allChars.length())); // selecting a random character from allChars
str.append(c); // appending the randomly selected character to str
}
// hashing str & checking if the hash matches res
if (hashF1(str.toString()) == res) {
collisionCount++; // iterating collisionCount if collision found
System.out.println(str); // printing the String that generated the collision
}
}
// printing the number of collisions found
System.out.printf("%d hash collisions found!", collisionCount);
}
}
else { // No <input>
System.out.println("Use: CT255_HashFunction1 <Input>");
}
}
private static int hashF1(String s){
int ret = -1, i;
int[] hashA = new int[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // i extended this array by 6 indices to make code more robust
// essentially, the extent of my improvements was just increasing the size of the hashA array
String filler, sIn;
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
if ((s.length() > 64) || (s.length() < 1)) { // String does not have required length
ret = -1;
}
else {
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
sIn = sIn.substring(0, 64); // // Limit string to first 64 characters
// System.out.println(sIn); // FYI
for (i = 0; i < sIn.length(); i++){
char byPos = sIn.charAt(i); // get ith character
hashA[0] += (byPos * 17); // Note: A += B means A = A + B
hashA[1] += (byPos * 31);
hashA[2] += (byPos * 101);
hashA[3] += (byPos * 79);
hashA[4] += byPos * 83;
hashA[5] += byPos * 89;
hashA[6] += byPos * 103;
hashA[7] += byPos * 107;
hashA[8] += byPos * 109;
hashA[9] += byPos * 113;
}
hashA[0] %= 255; // % is the modulus operation, i.e. division with rest
hashA[1] %= 255;
hashA[2] %= 255;
hashA[3] %= 255;
hashA[4] %= 255;
hashA[5] %= 255;
hashA[6] %= 255;
hashA[7] %= 255;
hashA[8] %= 255;
hashA[9] %= 255;
ret = hashA[0] + (hashA[1] * 256) + (hashA[2] * 256 * 256) + (hashA[3] * 256 * 256 * 256) + (hashA[4] * 256*256*256*256) + (hashA[5] * 256*256*256*256*256) + (hashA[6] * 256*236*256*256*256*256)
+ (hashA[6] * 256*256*256*256*256*256) + (hashA[7] * 256*256*256*256*256*256*256) + (hashA[8] * 256*256*256*256*256*256*256*256) + (hashA[9] * 256*256*256*256*256*256*256*256*256);
if (ret < 0) ret *= -1;
}
return ret;
}
}