How to Compare Two Hashes

How do I compare two hashes?

You can compare hashes directly for equality:

hash1 = {'a' => 1, 'b' => 2}
hash2 = {'a' => 1, 'b' => 2}
hash3 = {'a' => 1, 'b' => 2, 'c' => 3}

hash1 == hash2 # => true
hash1 == hash3 # => false

hash1.to_a == hash2.to_a # => true
hash1.to_a == hash3.to_a # => false


You can convert the hashes to arrays, then get their difference:

hash3.to_a - hash1.to_a # => [["c", 3]]

if (hash3.size > hash1.size)
difference = hash3.to_a - hash1.to_a
else
difference = hash1.to_a - hash3.to_a
end
Hash[*difference.flatten] # => {"c"=>3}

Simplifying further:

Assigning difference via a ternary structure:

  difference = (hash3.size > hash1.size) \
? hash3.to_a - hash1.to_a \
: hash1.to_a - hash3.to_a
=> [["c", 3]]
Hash[*difference.flatten]
=> {"c"=>3}

Doing it all in one operation and getting rid of the difference variable:

  Hash[*(
(hash3.size > hash1.size) \
? hash3.to_a - hash1.to_a \
: hash1.to_a - hash3.to_a
).flatten]
=> {"c"=>3}

Compare two hashes using Powershell

Get-FileHash returns an object containing, among other things, the hash.
To get the actual hash, you'll have use the Hash property of the object.

So you could do

$fileHash = (Get-FileHash Release.zip -a md5).Hash

Get-Content might return a single string but it also might return an array of strings, depending on newlines being present in the file you are reading. Assuming the file only contains a hash, following might suffice

$checkHash = Get-Content release821hash.txt

Stitching both together, your check could be

$fileHash -eq $checkHash

or

((Get-FileHash Release.zip -a md5).Hash) -eq (Get-Content release821hash.txt)

Note: if you know the hashes to be equal but the check returns false, most likely there are additional characters in the release821hash.txt file and you'll have to strip those from the string.

Compare two hashes by value to get keys/values where the 2nd is greater

If I understand correctly, you want something like this:

# For each key in %dec28
for my $k (keys %dec28) {
# If the same key exists in %dec29
# And the %dec29 value is greater than the %dec28 value
if (exists $dec29{$k} and $dec29{$k} > $dec28{$k}) {
# Print something useful
print "$k: $dec28{$k} -> $dec29{$k}\n";
}
}

How to compare this two hashes in ruby

1. Symbolize keys

These hashes are not equal because the keys are not equal. If you want to compare the values, no matter whether the keys are strings or symbols you can just transform the keys using to_sym. (Note that this will not transform nested keys).

first_hash.transform_keys(&:to_sym) == second_hash.transform_keys(&:to_sym)

2. Compare as JSON (NOT RECOMMENDED)

I do not recommend this, but since it is technically possible, I included it here for fun and informational purposes.

Another way you can do this is to check whether the JSON representation is the same. It is probably slower, and requires the keys to be in the same order in each hash.

require 'json'
first_hash.to_json == second_hash.to_json

Compare values of two hashes with mixed types

First, Perl does not have types. It does not distinguish between strings and numbers (on the outside).

Furthermore, it does not make a difference between numbers and strings on this level. The numerical context and string context matters if you check what's greater or less than. Consider this:

my $foo = 200;
my $bar = 99;
print $foo > $bar ? $foo : $bar;

Obviously it will print 200, because 200 is numerically larger than 99.

my $foo = 200;
my $bar = 99;
print $foo gt $bar ? $foo : $bar;

But this will print 99, because 9 is alphanumerically (as in string) greater than 2. It compared the numbers of the code points for the characters.

But if all you want to do is check for inequality, the ne operator is fine. Even when you are not sure whether there are things other than numbers in your input.

foreach my $key ( keys(%$hash1) ) {
if ($hash1->{$key} ne $hash2->{$key}) {
print($key);
}
}

eq (and ne) are smart enough to see if a number was initially a string or a number without quotes, because the internal representation of those differs.

Warning, technical details ahead.

Scalar values are saved in _SV_s. These in terms can contain different things. There's a special internal type for simple integers called IV, and also one called PV for strings. Perl internally converts between those two as needed when you use numbers inside of strings, or vise versa.

You can get some debugging information about the internal representation of data with Dump from Devel::Peek.

use Devel::Peek;

Dump("01");
Dump(01);

This will output:

SV = PV(0x19560d0) at 0x19327d0
REFCNT = 1
FLAGS = (POK,READONLY,IsCOW,pPOK)
PV = 0x1c94fd0 "01"\0
CUR = 2
LEN = 10
COW_REFCNT = 0
SV = IV(0x19739b0) at 0x19739c0
REFCNT = 1
FLAGS = (IOK,READONLY,pIOK)
IV = 1

As you can see, the first one is a string, and the second one is a number.
But if we do this

print "01" eq 01;

there is no output, because the 01 is an integer and will be converted to "1" for comparison. Since the 0 of "01" is not equal to 1, nothing gets printed.


If the values of your data structures are more complex, you need to walk the structure. Each type of element needs to have its own handling. There could be array references, hash references, scalar references, scalars, glob references, dualvars and so on. There might be objects that you want to treat specially.

I suggest taking a look at how Test::Deep implements this. If you decide to use it in production code (and not a unit test), you can use Test::Deep::NoTest.

How do I compare two hashes using SHA256Managed?

First, you should store salt with the hashed value.

Next, when user trying to authenticate with some login and password you can use next scenario:

  1. Retrieve user data from database by Login (for example, GetUser(login)). User class should contains login, hashed password and salt.
  2. If there is no user with that login, then fail authentication. Else execute CalculateHash() with password and salt from the User class retrieved on previous step.
  3. Compare 2 strings: first is hashed password from User class and second from the CalculateHash() method. If hashes are equals then user successfully authenticated.

nodejs - how to compare two hashes password of bcrypt

This is impossible by design - as a core security property of true password hashing.

If you could compare two password hashes without knowing the original password, then if an attacker cracked one password on the system, they would instantly know the passwords of all users who are using that password, without any additional work. It should be immediately obvious why this would be a bad thing.

For example, if passwords were stored using a hash inappropriate for password storage (such as MD5), then if 50 users had a password of 'password', then all of their hashed passwords would have the identical MD5 hash ('5f4dcc3b5aa765d61d8327deb882cf99'), and cracking one of them would reveal every user's password.

You can't do that with a modern password hash like bcrypt. The only way to "compare" two modern password hashes is to know the plaintext in advance, and then apply the algorithm using the salt in each hash. And even if two users have the same password, the attacker has to perform the same expensive computation to crack each of them independently, because the unique salts make each hash unique.

More generally - and this may sound a bit bold - but there is no legitimate use case for any system or administrator to ever compare two different users' passwords. User passwords should be 100% independent and 100% opaque to the system once stored. If a system or business case requires this kind of comparison, it should be redesigned to eliminate that requirement.

Compare hashes in c

Two points:

  1. Don't use strcmp but rather memcmp since the generated hash gen_hash won't have '\0' at the end.

  2. You defined orig_hash as

    unsigned char orig_hash[] =
    {"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"};

which is a string of characters. You should define it as a array of numbers:

unsigned char orig_hash[] = {0xba, 0x78, 0x16, 0xbf, ...};

compare two hashes in ruby

# normalization
h1, h2 = [hash1, hash2].map do |h|
h.map do |k, v|
[k.to_s.downcase, v.to_s.to_i.to_s == v.to_s ? v.to_i : v]
end.to_h
end

Now we are ready to compare:

h1.reject { |k, v| h2[k].nil? || h2[k] == v }
#⇒ { "g" => "2.25000000" }

This might be printed, formatted etc as you want.



Related Topics



Leave a reply



Submit