I wrote a simplified version of SHA256 algorithm and tried some inputs. At first it seems to work fine(although the output is a bit different from the online codes), but when I tried with input "admin", it outputs the same hash regardless of salt String added to input. Surprisingly, if input is "admi", "admin1" or "admin1234", it still outputs the same hash. I didn't find any other input that has the same problem.
Here's the code:
package src.encrypt;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Random;
public class Password {
private String salt;
private String hash;
private String saltGen() {
final String hex = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random rnd = new Random(Instant.now().toEpochMilli());
char[] salt = new char[16];
for (int i = 0; i < 16; i++) {
int n = rnd.nextInt(hex.length());
salt[i] = hex.charAt(n);
}
return String.valueOf(salt);
}
public Password() {
};
public Password(String pass) {
salt = saltGen();
String p = new String(pass + salt);
hash = sha256(p);
}
public String getSalt() {
return salt;
}
public String getHash() {
return hash;
}
public boolean compareHash(String h) {
return getHash().equals(sha256(h + getSalt()));
}
// SHA-256 Hashing Algorithm
public String sha256(String str) {
// Pre-processing
ArrayList<String> hash = new ArrayList<>();
byte[] bytes = str.getBytes();
int i = 0;
for (i = 0; i < bytes.length - 4; i += 4) {
String tmp = String.format("%8s", Integer.toBinaryString(bytes[i] & 0xff)).replace(' ', '0')
+ String.format("%8s", Integer.toBinaryString(bytes[i + 1] & 0xff)).replace(' ', '0') +
String.format("%8s", Integer.toBinaryString(bytes[i + 2] & 0xff)).replace(' ', '0') +
String.format("%8s", Integer.toBinaryString(bytes[i + 3] & 0xff)).replace(' ', '0');
hash.add(tmp);
}
String temp = new String();
for (int j = i; j < bytes.length; j++)
temp = new String(temp + String.format("%8s", Integer.toBinaryString(bytes[j] & 0xff)).replace(' ', '0'));
if (temp.length() < 32)
temp = new String(temp + "10000000");
while (temp.length() < 32)
temp = new String(temp + "00000000");
hash.add(temp);
int l = 14 - hash.size() % 16;
for (i = 0; i < l; i++)
hash.add(new String("00000000000000000000000000000000"));
String tmp = String.format("%64s", Long.toBinaryString((long) (bytes.length * 8))).replace(' ', '0');
hash.add(tmp.substring(0, 32));
hash.add(tmp.substring(32));
// Init Hash values
int H[] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
// Init Round Constants
int K[] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
// Create Message Schedule and Compressing
l = hash.size() / 16;
int a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7];
ArrayList<Integer> w = new ArrayList<>();
for (i = 0; i < l; i++) {
for (int j = i * 16; j < (i + 1) * 16; j++) {
w.add(Integer.parseInt(hash.get(j), 2));
}
for (int j = 16; j < 64; j++) {
int s0 = rightRotate1(w.get(j - 15));
int s1 = rightRotate2(w.get(j - 15));
w.add(w.get(j - 16) + s0 + w.get(j - 7) + s1);
}
for (int j = 0; j < 64; j++) {
int temp1 = h + rightRotate3(e) + ((e & f) ^ (~e & g)) + K[i] + w.get(i);
int temp2 = rightRotate4(a) + ((a & b) ^ (a & c) ^ (b & c));
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}
// Modify final values
H[0] = H[0] + a;
H[1] = H[1] + b;
H[2] = H[2] + c;
H[3] = H[3] + d;
H[4] = H[4] + e;
H[5] = H[5] + f;
H[6] = H[6] + g;
H[7] = H[7] + h;
}
// Concatenate final hash
String s = new String();
for (i = 0; i < 8; i++) {
s = new String(s + String.format("%08X", H[i]).toLowerCase());
}
return s;
};
// right rotate
private int rotr(int x, int n) {
return (x >>> n) | (x << (32 - n));
}
private int rightRotate3(int x) {
return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
}
private int rightRotate4(int x) {
return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
}
private int rightRotate1(int x) {
return rotr(x, 7) ^ rotr(x, 18) ^ x >>> 3;
}
private int rightRotate2(int x) {
return rotr(x, 17) ^ rotr(x, 19) ^ x >>> 10;
}
With input "admin", output is always "0920b401857e70a28c7b645c04195f2f15b54b98a7e7810f6d46c3a9c74adf6a"
Can anyone spot some bugs or mistakes that I made?
Please note that I'm new to Java so some methods I use maybe unefficient.
EDIT
Here's how I call the method:
// Main.java
import src.encrypt.Password;
public class Main {
public static void main(String[] args) {
String pass = "admin";
Password p = new Password(pass);
System.out.println(p.getSalt()); // different calls, different values
System.out.println(p.getHash()); // different calls, same value
}
}
The error occurs in the processing of the message schedule array (the w arraylist, the terminology is from https://en.wikipedia.org/wiki/SHA-2):
for (int j = 0; j < 64; j++) {
int temp1 = h + rightRotate3(e) + ((e & f) ^ (~e & g)) + K[i] + w.get(i);
int temp2 = rightRotate4(a) + ((a & b) ^ (a & c) ^ (b & c));
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}
Your loop variable here is j, but you use the variable i to access the message schedule array (i is used in the outer loop that processes the message chunks).
The correct code is
for (int j = 0; j < 64; j++) {
int temp1 = h + rightRotate3(e) + ((e & f) ^ (~e & g)) + K[j] + w.get(j);
int temp2 = rightRotate4(a) + ((a & b) ^ (a & c) ^ (b & c));
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}
I have implemented a convolution filter in java. I did this a while back in ap cs but now I actually need it for something, so I re implemented it to make sure I still know how to do it. Unfortunately I lost my working copy so I can't compare current code to my previous working code. I am pretty sure I am implementing the algorithm correctly, but the code is still not working properly. Can an experienced programmer please explain what I am doing wrong.
Here is the Convolution class:
import java.awt.*;
import java.util.Arrays;
public class ConvolutionFilter {
private int[][] image;
private int[][] weights;
private double[][] doubleWeights;
private int[][] convolved;
public ConvolutionFilter(int[][] image, int[][] weights) {
this.image = image;
this.weights = weights;
convolve();
}
public void convolve() {
int sum;
int[][] convolved = new int[image.length][image[0].length];
for (int r = 0; r < convolved.length - weights.length - 1; r++) {
for (int c = 0; c < convolved[r].length - weights.length - 1; c++) {
sum = 0;
for (int i = 0; i < weights.length; i++) {
for (int j = 0; j < weights[i].length; j++) {
sum += image[r + i][c + j] * weights[i][j];
}
}
convolved[r][c] = sum / weight();
}
}
this.convolved = convolved;
}
public int numWeights() {
return weights.length * weights[0].length;
}
public int weight() {
int sum = 0;
for (int r = 0; r < weights.length; r++) {
for (int c = 0; c < weights[r].length; c++) {
sum += weights[r][c];
}
}
if (sum == 0) return 1; else return sum;
}
public int[][] getConvolved() {
return convolved;
}
}
Any help is appreciated!
To adapt this to RGB, the arithmetic should be done per channel instead of over the packed representation, for example (not tested)
public void convolve() {
int[][] convolved = new int[image.length][image[0].length];
double invScale = 1.0 / weight();
for (int r = 0; r < convolved.length - weights.length - 1; r++) {
for (int c = 0; c < convolved[r].length - weights.length - 1; c++) {
int rsum = 0, gsum = 0, bsum = 0;
for (int i = 0; i < weights.length; i++) {
for (int j = 0; j < weights[i].length; j++) {
int pixel = image[r + i][c + j];
int w = weights[i][j];
rsum += ((pixel >> 16) & 0xFF) * w;
gsum += ((pixel >> 8) & 0xFF) * w;
bsum += (pixel & 0xFF) * w;
}
}
rsum = (int)(rsum * invScale);
gsum = (int)(gsum * invScale);
bsum = (int)(bsum * invScale);
convolved[r][c] = bsum | (gsum << 8) | (rsum << 16) | (0xFF << 24);
}
}
this.convolved = convolved;
}
I've been trying to write a program to print the min and max value of 5 integer type variables, using no arrays and only swapping using this technique
if (x > y) {
int tmp = x;
x = y;
y = tmp;
}
now this is what I came up with ( although I know it's possible with only 6 swaps however I can't figure it out):
Scanner input = new Scanner(System.in);
int a = input.nextInt();
int b = input.nextInt();
int c = input.nextInt();
int d = input.nextInt();
int e = input.nextInt();
//storing max value in a all the way, and min value in b
if (a < b) {
int tmp = a;
a = b;
b = tmp;
}
if (a < c) {
int tmp = a;
a = c;
c = tmp;
}
if (a < d) {
int tmp = a;
a = d;
d = tmp;
}
if (a < e) {
int tmp = a;
a = e;
e = tmp;
}
if (c < b) {
int tmp = b;
b = c;
c = tmp;
}
if (d < b) {
int tmp = b;
b = d;
d = tmp;
}
if (e < b) {
int tmp = b;
b = e;
e = tmp;
}
System.out.println(b +"\n" + a);
Now this should work, but I also needed to write a code to make sure the program works fine, so I could check all the combinations with 0's and 1's in them.
i.e 2^5=32 combinations. and if one of them fails print it.
I've tried to do this :
for (int a = 0; a <= 1; a++) {
for(int b = 0; b <= 1; b++) {
for(int c = 0; c <= 1; c++) {
for(int d = 0; d <= 1; d++) {
for(int e = 0; e <= 1; e++) {
if (a < b){
int tmp = a;
a = b;
b = tmp;
}
if (a < c) {
int tmp = a;
a = c;
c = tmp;
}
if (a < d) {
int tmp = a;
a = d;
d = tmp;
}
if (a < e) {
int tmp = a;
a = e;
e = tmp;
}
if (c < b) {
int tmp = b;
b = c;
c = tmp;
}
if (d < b) {
int tmp = b;
b = d;
d = tmp;
}
if (e < b) {
int tmp = b;
b = e;
e = tmp;
}
System.out.println(b + "\n" + a);
}
}
}
}
}
but this doesn't work because once there is a "1" in any variable a gets it and then I'm not gonna be able to run the combinations properly..
****basically this is a tester for the code within the loop, so it should test 0000-11111 and print something like verified if all works well, or print the combination for which it got the wrong result.. however I can't see how it's gonna do that .****
any suggestions? no arrays , swapping only...
thanks ahead
I would use Math.min(int, int) and Math.max(int, int) and a long chain of invocations. Like,
Scanner input = new Scanner(System.in);
int a = input.nextInt();
int b = input.nextInt();
int c = input.nextInt();
int d = input.nextInt();
int e = input.nextInt();
int min = Math.min(Math.min(Math.min(Math.min(a, b), c), d), e);
int max = Math.max(Math.max(Math.max(Math.max(a, b), c), d), e);
Your "swapping piece of code" makes no sense. Here is another implementation
Scanner input = new Scanner(System.in);
int a = input.nextInt();
int b = input.nextInt();
int c = input.nextInt();
int d = input.nextInt();
int e = input.nextInt();
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
min = (a < min) ? a : min;
min = (b < min) ? b : min;
min = (c < min) ? c : min;
min = (d < min) ? d : min;
min = (e < min) ? e : min;
max = (a > max) ? a : max;
max = (b > max) ? b : max;
max = (c > max) ? c : max;
max = (d > max) ? d : max;
max = (e > max) ? e : max;
Why don't you store the a,b,c,d,e values in the innermost loop and reassign it back to the variables again after your swapping piece of code? Like so,
public static void main(String args[]) {
for (int a=0 ;a<=1 ;a++ ){
for(int b=0 ;b<=1 ;b++ ){
for(int c=0 ;c<=1 ;c++ ){
for(int d=0 ;d<=1 ;d++ ){
for(int e=0 ; e<=1 ;e++ ){
// Store the variable values
int ap = a;
int bp = b;
int cp =c;
int dp = d;
int ep = e;
// Swapping logic for finding min and max
// Due to swapping, the values of a,b,c,d,e may change
if ( a < b){
int tmp = a;
a=b;
b=tmp;
}
if ( a < c){
int tmp = a;
a=c;
c=tmp;
}
if ( a < d){
int tmp = a;
a=d;
d=tmp;
}
if ( a < e){
int tmp = a;
a=e;
e=tmp;
}
if ( c < b){
int tmp = b;
b=c;
c=tmp;
}
if ( d < b){
int tmp = b;
b=d;
d=tmp;
}
if ( e < b){
int tmp = b;
b=e;
e=tmp;
}
System.out.print(a+""+b+""+c+""+d+""+e+" ");
System.out.println(b + " " + a);
// Reassign the variable values
a = ap;
b = bp;
c=cp;
d=dp;
e=ep;
}
}
}
}
}
}
I'm very new to Java. Having a problem with this block of code. Attempting to find minimum number of coins needed to pay a certain amount (in example 398 cents).
I'm getting an error unexpected type. Required: variable. found: Value. after I attempt to subtract on lines 20, 25, 30, 35, 40, 45 and 50. I want to subtract a value. I think I have to use a method but I'm unsure how. Any help would be very appreciated.
public class MakingChange {
public static void main(String[] args) {
int a = 398;
int b;
int c;
int d;
int e;
int f;
int g;
int h;
int j;
int k;
int i;
int l;
int m;
int n;
int o;
if (a > 0) {
if (a >= 200) {
i = (int) a / 200;
a - i * 200 = b;
} else {
a = b;
}
if (b >= 100) {
j = (int) a / 100;
b - j * 100 = c;
} else {
b = c;
}
if (c >= 25) {
k = (int) c / 25;
c - k * 25 = d;
} else {
c = d;
}
if (d >= 100) {
l = (int) d / 100;
b - l * 100 = c;
} else {
d = e;
}
if (e >= 10) {
m = (int) e / 10;
e - m * 10 = f;
} else {
e = f;
}
if (f >= 5) {
n = (int) f / 5;
f - n * 5 = g;
} else {
f = g;
}
if (g >= 1) {
o = (int) g / 1;
g - o = h;
} else {
g = h;
}
System.out.println(i + j + k + l + m + n + o);
}
}
}
An assignment operation in Java language involves the following syntax:
Variable = expression
It first evaluates the expression on the right side and assigns the resulting value to the operand on its left. So going by this rule, LHS of an assignment must strictly be a variable which can be reference to primitive type, User Defined Type or an Array.
The blocks in your code which violate this principle are:
a - i * 200 = b;
b - j * 100 = c;
c - k * 25 = d;
b - l * 100 = c;
e - m * 10 = f;
f - n * 5 = g;
g - o = h;
You can't say things like g-o=h. That's putting a value expression (g-h) on the left side of an assignment. If you want to assign g-o to h, then say h = g-o. You have a bunch of those.
Got this code in java :
public static int readHexInteger(ChannelBuffer buf, int length) {
int result = 0;
for (int i = 0; i < length / 2; i++) {
int b = buf.readUnsignedByte();
result *= 10;
result += b >>> 4;
result *= 10;
result += b & 0x0f;
}
if (length % 2 == 1) {
int b = buf.getUnsignedByte(buf.readerIndex());
result *= 10;
result += b >>> 4;
}
return result;
}
I'm trying to code the same thing but with nodejs.
Is there any java/nodejs hacker in the room ?
Thanks in advance !