Reputation: 37
#!/bin/bash
# Program's Purpose: Compute time elapsed between epoch time and current time
# Produce an MD5 hash from that time
# Get code from that hash
# compute time elapsed in seconds between epoch time and current time
#EPOCH=$(date -u -d '2001-02-03 04:05:06' '+%F %H:%M:%S')
#CURRENT=$(date -u -d '2010-06-13 12:55:34' '+%F %H:%M:%S')
# code: dd15
EPOCH=$(date -u -d '1999-12-31 23:59:59' '+%F %H:%M:%S')
CURRENT=$(date -u -d '2013-05-06 07:43:25' '+%F %H:%M:%S')
# interval is time elapsed minus time elapsed % 60
echo $EPOCH
echo $CURRENT
read YEAR1 M1 DAY1 HOUR1 MIN1 SEC1 <<< "${EPOCH//[:-]/ }"
read YEAR2 M2 DAY2 HOUR2 MIN2 SEC2 <<< "${CURRENT//[:-]/ }"
echo $YEAR1 $M1 $DAY1 $HOUR1 $MIN1 $SEC1
# date in seconds from
sec1=$(date -d "$EPOCH" -u +%s)
sec2=$(date -d "$CURRENT" -u +%s)
echo $sec1
echo $sec2
# get the difference from the two times
difference=$((sec2 - sec1))
difference=$((difference - ((difference % 60))))
echo $difference
# get the hash from the time
hash=$(echo -n $difference | md5sum | tr -d '\n')
hash=$(echo -n $hash | md5sum | tr -d '\n')
echo $hash
# creating two strings, one with all of the letters
# the other with all of the numbers
letter=$(echo $hash | sed 's/[0-9]*//g' | cut -c1-2)
echo $letter
num=$(echo $hash | sed 's/[^0-9]*//g')
echo $num
#num=$(echo $num | cut -c1-2)
#echo $num
# getting the last two numbers in reverse order
num1=$(echo ${num: -1})
num=$(echo "${num::-1}")
echo $num
num2=$(echo ${num: -1})
code="$letter$num1$num2"
echo $code
I'm trying to write a program that takes an epoch time and current time, computes the difference in seconds, and then creates a code by doing a double md5 hash on the time in seconds. By what times I have entered in currently, the difference in seconds should be 421, 141, 406, and the 'code' is supposed to be based on 60-second intervals, so the code I'm trying to generate should come from 421, 141, 380.
The resulting hash should be
042876ca07cb2d993601fb40a1525736
, but I am getting
d49904f9e7e62d0ff16e523d89be08eb
. Can anyone tell me what I'm doing
wrong exactly?
I read that bash leaves a newline at the end of
strings, so I ran echo with -n
option to remove that newline, but I am
still not getting the preferred results.
Upvotes: 1
Views: 1813
Reputation: 189297
The output of md5sum
on many platforms is not just the MD5 sum. For example, on a GNU/Linux system, you get
debian$ echo -n 401 | md5sum
816b112c6105b3ebd537828a39af4818 -
Notice that the output has two fields: The actual MD5 sum, followed by two spaces, followed by the input file name (where -
stands for standard input).
(By contrast, on OSX, and I would expect most *BSDs, you get
yosemite$ echo -n 401 | md5
816b112c6105b3ebd537828a39af4818
Here, you'll notice that the name of the MD5 utility is different.)
The fix should be simple. I have refactored your code to (a) prefer the portable printf
over the less portable echo -n
; (b) remove the completely superfluous final tr -d '\n'
(newlines are trimmed off the end of the captured variable by the shell already); and (c) fold everything into a single pipeline.
hash=$(printf '%s' "$difference" | md5sum | cut -d ' ' -f 1 | tr -d '\n' |
md5sum | cut -d ' ' -f 1)
echo "$hash"
For completeness, this code also has proper quoting; it's not strictly necessary here (but it would have been if you really needed to preserve the spacing in the value you originally obtained from md5sum
, for example) but omitting quotes is a common newbie problem which should be avoided.
(Capturing a variable just so you can echo
it is also a common newbie antipattern; but your code will want to use the variable hash
subsequently.)
Repeated code is always a bad smell; maybe provide a function which performs the same job as the *BSD md5
utility;
md5 () { md5sum "$@" | cut -d ' ' -f 1; }
hash=$(printf '%s' "$difference" | md5 | tr -d '\n' | md5)
Upvotes: 2