Skip to main content
spelling fixes
Source Link
Toby Speight
  • 88.4k
  • 14
  • 104
  • 327

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusionscollisions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfillfulfil these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfill these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collisions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfil these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292
Rollback to Revision 2
Source Link
pacmaninbw
  • 26.1k
  • 13
  • 47
  • 114

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfill these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292

Updated version, as suggested in reviews:

(better performance, less use of magic constants)

#!/bin/bash
my_hash () {
  s=${1}aaaa
  s=${s:0:4}
  a=$(printf '%d' "'a")  # ordinal of 'a'
  hash=0
  multiplier=1
  for i in {0..3};
  do
    j=$(printf '%d' "'${s:$i:1}")  # ordinal of ith char
    hash=$((hash+(multiplier*(j-a)*961)))
    multiplier=$((multiplier*26))
  done
  hash=$((((10000*hash)/456976)%10000))  # 456976 is 26**4
  printf '%04d\n' "$hash"
}
my_hash "$1"

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfill these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292

Updated version, as suggested in reviews:

(better performance, less use of magic constants)

#!/bin/bash
my_hash () {
  s=${1}aaaa
  s=${s:0:4}
  a=$(printf '%d' "'a")  # ordinal of 'a'
  hash=0
  multiplier=1
  for i in {0..3};
  do
    j=$(printf '%d' "'${s:$i:1}")  # ordinal of ith char
    hash=$((hash+(multiplier*(j-a)*961)))
    multiplier=$((multiplier*26))
  done
  hash=$((((10000*hash)/456976)%10000))  # 456976 is 26**4
  printf '%04d\n' "$hash"
}
my_hash "$1"

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfill these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292
additional code
Source Link

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfill these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292

Updated version, as suggested in reviews:

(better performance, less use of magic constants)

#!/bin/bash
my_hash () {
  s=${1}aaaa
  s=${s:0:4}
  a=$(printf '%d' "'a")  # ordinal of 'a'
  hash=0
  multiplier=1
  for i in {0..3};
  do
    j=$(printf '%d' "'${s:$i:1}")  # ordinal of ith char
    hash=$((hash+(multiplier*(j-a)*961)))
    multiplier=$((multiplier*26))
  done
  hash=$((((10000*hash)/456976)%10000))  # 456976 is 26**4
  printf '%04d\n' "$hash"
}
my_hash "$1"

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfill these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292

I'm looking for a (possibly cryptographic strong) hash function in Bash with the following properties:

  • The input is only a string with 4 lower-case characters: aaaa to zzzz
  • The output should be a decimal number (with leading zeros) in range: 0000 to 9999
  • Low number of collusions and hash values distributed as evenly as possible
  • Surjective (each output should appear)
  • Chaos (should have a good diffusion of hash values)
  • Optional: Confusing (it should not be possible to draw any conclusions about the input value from the hash value)

I have not yet found a (simple) algorithm that would fulfill these requirements.

This is my approach. How would you rate it?

#!/bin/bash
# ord() - converts ASCII character to its decimal value
ord() {
  printf '%d' "'$1"
}
my_hash_4 () {
  s=$1
  while (( ${#s} < 4 ));
  do
    s="${s}a"
  done
  hash=0
  multiplier=1
  for i in $(seq 0 3);
  do
    j=$(ord "${s:$i:1}")
    hash=$((hash+(multiplier*(j-97)*961)))
    multiplier=$((multiplier*26))
  done
  # (int) (10_000 / Math.pow(26, 4) * hash) % 10_000
  hash=$((((10000000*hash)/456976000)%10000))
  printf '%04d\n' "$hash"
}
my_hash_4 "$1"

Example output:

bash my_hash.sh aaaa
0000
bash my_hash.sh baaa
0021
bash my_hash.sh abaa
0546
bash my_hash.sh bbaa
0567
bash my_hash.sh zzzz
9978
bash my_hash.sh hallo
2292

Updated version, as suggested in reviews:

(better performance, less use of magic constants)

#!/bin/bash
my_hash () {
  s=${1}aaaa
  s=${s:0:4}
  a=$(printf '%d' "'a")  # ordinal of 'a'
  hash=0
  multiplier=1
  for i in {0..3};
  do
    j=$(printf '%d' "'${s:$i:1}")  # ordinal of ith char
    hash=$((hash+(multiplier*(j-a)*961)))
    multiplier=$((multiplier*26))
  done
  hash=$((((10000*hash)/456976)%10000))  # 456976 is 26**4
  printf '%04d\n' "$hash"
}
my_hash "$1"
Became Hot Network Question
corrected spelling, improved requirements description
Source Link
Loading
Source Link
Loading