Returning from /bin/sh Functions - sh

I've written a lot of Bash, but I now need to port some of my code into /bin/sh, and I'm observing strange behavior.
I have a function:
path_exists() {
path="$1" && shift
echo "$PATH" | tr ':' '\n' | while read path_entry ; do
test "$path" = "$path_entry" && return 0
done
return 1
}
I'm calling it like so:
if path_exists "/usr/bin" ; then
echo "it exists"
else
echo "it does not exist"
fi
If I run it with set -x, I see that return codes are overwritten:
+ path_exists /usr/bin
+ path=/usr/bin
+ shift
+ echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
+ tr : \n
+ read path_entry
+ test /usr/bin = /usr/local/sbin
+ read path_entry
+ test /usr/bin = /usr/local/bin
+ read path_entry
+ test /usr/bin = /usr/sbin
+ read path_entry
+ test /usr/bin = /usr/bin
+ return 0
+ return 1
+ echo it does not exist
Why is my function not respecting my return codes?

Why is my function not respecting my return codes?
Because pipe spawns a subshell, and you are only returning from a subshell. The same way:
echo | exit 0
will not exit your shell, only exit from | { the subshell on the right side of pipe; }. Or the same way func() { ( return 1; echo 123; ); return 0; }; func - the return 1 only affects the subshell.
The behavior is the same in ash, dash and in bash, but I think in POSIX sh it would be unspecified.
Aaaaanyway:
path_exists() {
case ":$PATH:" in
*:"$1":*) ;;
*) false; ;;
esac
}

Related

Listing SRC_URI of all packages/files needed to build Yocto image

I would like to list all files that bitbake will fetch when I bake an image.
Currently, I am able to get the SRC_URI of all files needed to bake a Yocto image by executing bitbake core-image-minimal -c fetchall and then parse log files.
Is there is a simpler way to get the same result without the need to download files ?
I am not sure bitbake supports such feature. Ideally, I am looking for a command that prints out the package name and lists all files with corresponding URL
> bitbake core-image-minimal -c fetchall --print-only
Generally bitbake doesn't provides such functionality.
But I was able to create a simple solution witch creating simple .bbclass file which is inherited in all recipes, by adding it into local.conf file, please see my steps in order to archive that:
Steps:
let's create a class print-src.bbclass file used to get and print SRC_URI variable (remember to store this class file in layer which is available in conf/bblayers.conf):
$ cat print-src.bbclass
python do_print_src () {
# should probably be indented
srcuri = d.getVar('SRC_URI', True).split()
bb.warn("SRC_URI look like: %s" % srcuri)
}
addtask do_print_src before do_fetch
Add INHERIT += "print-src" into Your conf/local.conf file
Edit: it is important to use bitbake --runonly option, that allows to run specific task of the taskgraph for the specified target (with --runonly option do_print_src needs to be used as print_src),
Edit: Please note that --runall=RUNALL and --runonly=RUNONLY was introduced with Yocto Sumo release 2.5,
$ bitbake core-image-minimal --runonly print_src
Loaded 1236 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "1.37.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal-4.8"
TARGET_SYS = "i586-poky-linux"
MACHINE = "qemux86"
DISTRO = "poky"
DISTRO_VERSION = "2.5"
TUNE_FEATURES = "m32 i586"
TARGET_FPU = ""
meta
meta-poky
meta-yocto-bsp = "master:13cc30cd7de4841990b600e83e1249c81a5171dd"
Initialising tasks: 100% |##########################################################################################################################################################################| Time: 0:00:00
NOTE: Executing RunQueue Tasks
WARNING: ptest-runner-2.2+gitAUTOINC+49956f65bb-r0 do_print_src: SRC_URI look like: ['git://git.yoctoproject.org/ptest-runner2']
WARNING: grep-3.1-r0 do_print_src: SRC_URI look like: ['http://ftp.gnu.org/gnu/grep/grep-3.1.tar.xz', 'file://0001-Unset-need_charset_alias-when-building-for-musl.patch']
...
...
NOTE: Tasks Summary: Attempted 201 tasks of which 0 didn't need to be rerun and all succeeded.
Summary: There were 202 WARNING messages shown.
Please see sample warning output log line:
WARNING: ptest-runner-2.2+gitAUTOINC+49956f65bb-r0 do_print_src: SRC_URI look like: ['git://git.yoctoproject.org/ptest-runner2'].
I patched poky to create *.src files in downloads that contains the effective fetch URL of the package.
bitbake/lib/bb/fetch2/__init__.py | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/bitbake/lib/bb/fetch2/__init__.py b/bitbake/lib/bb/fetch2/__init__.py
index b853da30bd..03e84e0919 100644
--- a/bitbake/lib/bb/fetch2/__init__.py
+++ b/bitbake/lib/bb/fetch2/__init__.py
## -1257,16 +1257,16 ## class FetchData(object):
# Note: .done and .lock files should always be in DL_DIR whereas localpath may not be.
if self.localpath and self.localpath.startswith(dldir):
- basepath = self.localpath
+ self.basepath = self.localpath
elif self.localpath:
- basepath = dldir + os.sep + os.path.basename(self.localpath)
+ self.basepath = dldir + os.sep + os.path.basename(self.localpath)
elif self.basepath or self.basename:
- basepath = dldir + os.sep + (self.basepath or self.basename)
+ self.basepath = dldir + os.sep + (self.basepath or self.basename)
else:
bb.fatal("Can't determine lock path for url %s" % url)
- self.donestamp = basepath + '.done'
- self.lockfile = basepath + '.lock'
+ self.donestamp = self.basepath + '.done'
+ self.lockfile = self.basepath + '.lock'
def setup_revisions(self, d):
self.revisions = {}
## -1607,6 +1607,15 ## class Fetch(object):
m = ud.method
localpath = ""
+ p = "%s.src"%ud.basepath
+ d = os.path.dirname(p)
+ if d != '':
+ bb.utils.mkdirhier(d)
+ with open(p, 'wb') as f:
+ data = "%s" % ud.url
+ f.write(bytes(data, 'ASCII'))
+ return True
+
if ud.lockfile:
lf = bb.utils.lockfile(ud.lockfile)
Running bitbake core-image-minimal -c fetchall results:
$> find downloads/ -name '*.src' | head -n 5
downloads/lzop-1.03.tar.gz.src
downloads/libtheora-1.1.1.tar.bz2.src
downloads/mpfr-3.1.5.tar.xz.src
downloads/makedevs.c.src
downloads/expat-2.2.0.tar.bz2.src
This is not an optimal solution but I hope that such feature gets its way to mainline stream.
I needed something like this and got part way there before now.
I can generate a messy list of URIs used by executing the following command:
bitbake -g zlib && cat recipe-depends.dot | \
grep -v -e '-native' | grep -v digraph | \
grep -v -e '-image' | awk '{print $1}' | \
sort | uniq | xargs -I {} -t bitbake -e {} | grep SRC_URI=
This gives you all the URIs and files used in a recipe and some comments.
Not a perfect solution but I will see if I can improve on it.
A bit manual and straight forward way is to build your image from scratch, and copy all the fetch logs, and go thru it.
$ mkdir fetch_logs
$ find tmp/work/ -type f -name log.do_fetch* | cpio -pdm fetch_logs
Now grep "Fetch(ing/er)" in this fetch_logs and it will provide info on which URL your recipe used to fetch the source. This will be helpful to see the final URI used to fetch in PREMIRROR based builds.
NOTE: if you have sstate-cache enabled and functional, you may not see do_fetch at all.
I wrote scripts based on the solution in the question.
Basically I need to make a cscope project of all the sources, and hence I need to list all URI and clone all repos.
I wrote 2 scripts 1) List all SRC_URI and Branches
2) Install(clone) all the code in a single directory
listURI.sh
#!/bin/bash
TMP_FILE="___x__2242230p.txt"
SRCH_FILE="log.do_fetch"
TIME=$(date +%Y-%m-%d-%H-%M)
OUT_FILE="Project-$TIME.txt"
DEF_BRANCH="master"
BRANCH=""
SRC_URI=""
function usage {
echo "Usage : $0 < -f | -g > <Component-List-file>"
echo "Options :"
echo " -f : Run bitbake fetch and collect URI"
echo " -g : Get URI from Already fetched Project"
}
if [ $# -eq 0 ]
then
usage
exit
fi
if [ "$1" == "-f" ] || [ "$1" == "-g" ];then
if [ "$1" == "-f" ] && [ -z "$2" ];then
echo "Should pass Project-Name after -f Option"
exit
fi
else
echo "Unknown Option"
usage
exit
fi
POKYROOTDIR=`basename "$PWD"`
#echo $POKYROOTDIR
if [[ $POKYROOTDIR != "build" ]];then
echo "You are not on poky/build (Sourced Poky) Directory"
exit 0
fi
POKYROOTDIR=$PWD
if [ "$1" == "-f" ];then
echo "Running === bitbake -c fetchall $2 -f --no-setscene =="
bitbake -c fetchall $2 -f --no-setscene
fi
if [ "$1" == "-g" ];then
if [ ! -d tmp/work ];then
echo " Please run == bitbake -c fetchall <image> -f --no-setscene == before this"
usage
exit
fi
fi
echo "Looking for URIs --- It may take couple of minuites!"
rm -rf $OUT_FILE
cd tmp/work
find . -name $SRCH_FILE -exec grep -i 'DEBUG: For url git' {} \; -print > $POKYROOTDIR/$TMP_FILE
cd $POKYROOTDIR
while IFS= read -r line
do
#echo "$line"
BRANCH=$(echo $line | awk -F"branch=" '/branch=/{print $2}' | sed -e 's/;/ /' | awk '{print $1}')
SRC_URI=$(echo $line | cut -d';' -f1-1 | awk -F"url" '/url/{print $2}' | awk '{print $1}' | sed -e 's/git:/ssh:/')
if [ ! -z "$BRANCH" ] && [ ! -z "$SRC_URI" ];then
echo "$BRANCH $SRC_URI" >> $OUT_FILE
elif [ ! -z "$SRC_URI" ];then
echo "$DEF_BRANCH $SRC_URI" >> $OUT_FILE
fi
if [ ! -z "$BRANCH" ];then
echo "Found URI : BRANCH:$BRANCH URI:$SRC_URI"
elif [ ! -z "$SRC_URI" ];then
echo "Found URI : BRANCH:Default URI:$SRC_URI"
fi
#echo "$BRANCH $SRC_URI" >> $OUT_FILE
done < "$TMP_FILE"
#echo "=================== OUT PUT ==========================="
#cat $OUT_FILE
rm -rf $TMP_FILE
echo "----------------INFO-----------------"
echo "Project Creation: Success"
echo "Project Path : $POKYROOTDIR"
echo "Project file : $OUT_FILE"
echo "-------------------------------------"
installURI.sh
#!/bin/bash
function usage {
echo "Usage : $0 <List-file>"
}
if [ $# -eq 0 ]
then
usage
exit
fi
if [ -z "$1" ];then
usage
exit
fi
if [ ! -z "$(ls -A $PWD)" ]; then
echo "Directory ($PWD) must be Empty.... else it will mess up project creation"
exit
fi
if [ ! -f $1 ];then
echo "list file ($1) not found"
usage
exit
fi
filename=$1
while read -r line; do
name="$line"
echo "Fetching Projects"
git clone -b $line
done < "$filename"
echo "----------------INFO-----------------"
echo "Project Creation: Success"
echo "Project Path : $PWD"
echo "-------------------------------------"

How to remove YAML frontmatter from markdown files?

I have markdown files that contain YAML frontmatter metadata, like this:
---
title: Something Somethingelse
author: Somebody Sometheson
---
But the YAML is of varying widths. Can I use a Posix command like sed to remove that frontmatter when it's at the beginning of a file? Something that just removes everything between --- and ---, inclusive, but also ignores the rest of the file, in case there are ---s elsewhere.
I understand your question to mean that you want to remove the first ----enclosed block if it starts at the first line. In that case,
sed '1 { /^---/ { :a N; /\n---/! ba; d} }' filename
This is:
1 { # in the first line
/^---/ { # if it starts with ---
:a # jump label for looping
N # fetch the next line, append to pattern space
/\n---/! ba; # if the result does not contain \n--- (that is, if the last
# fetched line does not begin with ---), go back to :a
d # then delete the whole thing.
}
}
# otherwise drop off the end here and do the default (print
# the line)
Depending on how you want to handle lines that begin with ---abc or so, you may have to change the patterns a little (perhaps add $ at the end to only match when the whole line is ---). I'm a bit unclear on your precise requirements there.
If you want to remove only the front matter, you could simply run:
sed '1{/^---$/!q;};1,/^---$/d' infile
If the first line doesn't match ---, sed will quit; else it will delete everything from the 1st line up to (and including) the next line matching --- (i.e. the entire front matter).
If you don't mind the "or something" being perl.
Simply print after two instances of "---" have been found:
perl -ne 'if ($i > 1) { print } else { /^---/ && $i++ }' yaml
or a bit shorter if you don't mind abusing ?: for flow control:
perl -ne '$i > 1 ? print : /^---/ && $i++' yaml
Be sure to include -i if you want to replace inline.
you use a bash file, create script.sh and make it executable using chmod +x script.sh and run it ./script.sh.
#!/bin/bash
#folder articles contains a lot of markdown files
files=./articles/*.md
for f in $files;
do
#filename
echo "${f##*/}"
#replace frontmatter title attribute to "title"
sed -i -r 's/^title: (.*)$/title: "\1"/' $f
#...
done
This AWK based solution works for files with and without FrontMatter, doing nothing in the later case.
#!/bin/sh
# Strips YAML FrontMattter from a file (usually Markdown).
# Exit immediately on each error and unset variable;
# see: https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -Ee
print_help() {
echo "Strips YAML FrontMattter from a file (usually Markdown)."
echo
echo "Usage:"
echo " `basename $0` -h"
echo " `basename $0` --help"
echo " `basename $0` -i <file-with-front-matter>"
echo " `basename $0` --in-place <file-with-front-matter>"
echo " `basename $0` <file-with-front-matter> <file-to-be-without-front-matter>"
}
replace=false
in_file="-"
out_file="/dev/stdout"
if [ -n "$1" ]
then
if [ "$1" = "-h" ] || [ "$1" = "--help" ]
then
print_help
exit 0
elif [ "$1" = "-i" ] || [ "$1" = "--in-place" ]
then
replace=true
in_file="$2"
out_file="$in_file"
else
in_file="$1"
if [ -n "$2" ]
then
out_file="$2"
fi
fi
fi
tmp_out_file="$out_file"
if $replace
then
tmp_out_file="${in_file}_tmp"
fi
awk -e '
BEGIN {
is_first_line=1;
in_fm=0;
}
/^---$/ {
if (is_first_line) {
in_fm=1;
}
}
{
if (! in_fm) {
print $0;
}
}
/^(---|...)$/ {
if (! is_first_line) {
in_fm=0;
}
is_first_line=0;
}
' "$in_file" >> "$tmp_out_file"
if $replace
then
mv "$tmp_out_file" "$out_file"
fi

Zsh executing two commands in a row independent of success

I would like to execute two commands in a row independent of the failure or success of the previous one, so I know that || and && will not work. What can I do in this case? I would like to have the shell wait for the first command to finish if it is successful; hence ; does not work either.
EDIT: I apologize the shell would be zsh and I run a shell script sending commands to different screens as seen below:
#! /bin/zsh
### Script for running everything in screens ###
### System argument screen name suffix ###
echo You have the following screens running:
screen -ls
sigarr=(NM1 NM2 NM3 Scenario4 Scenario6)
puarr=(50PU 140PU)
lumarr=(30 300 3000)
echo Please type 1 for 50PU samples and 2 for 140PU samples
read PU
if [[ $PU -ne 1 && $PU -ne 2 ]] ; then
echo You have to enter 1 or 2
return 1
fi
echo Please type 1 for 300fb-1 and 2 for 3000fb-1
read lum
if [[ $lum -ne 1 && $lum -ne 2 ]] ; then
echo You have to enter 1 or 2
return 1
fi
if [ $PU = 1 ]; then
let "lum = $lum + 1"
#echo $lum
fi
ex NEWrunReader.py <<EOEX
:43s/Lumi.*/Lumi=$lumarr[lum]/
:x
EOEX
echo Compiling the reader file!!!
root -l << EOF
.L readerSummerStd.C+
EOF
if [ $PU = 2]; then
let "lum = $lum + 1"
fi
echo Press any key to proceed or Ctrl+C to abort!
read
for sigind in $sigarr
do
screen -dmS "${sigind}_${lumarr[lum]}_${puarr[PU]}_${1}"
sleep 0.1
screen -S "${sigind}_${lumarr[lum]}_${puarr[PU]}_${1}" -p 0 -X stuff "./NEWrunReader.py SummerStd $puarr[PU]_$sigind $1 >& "${sigind}_${lumarr[lum]}_${1}".txt &;exit"$'\r'
done
return 0
Use | or & instead of usng || or &&
for zsh, especially on a mac, it's ;
try it from the terminal
sleep 3 ; echo "hello"
There will be a 3 seconds delay then it will print hello

Using CVS diff to get line numbers of mofied/added/deleted code

I have a very large project where we have made changes to lots of files. Now we need to exactly know which line numbers we have changed/added so that we can run some other tool on that particular line only.
While searching for the answer i found this as an answer to some other question..
echo ${f}:
for n in $(git --no-pager blame --line-porcelain $1 |
awk '/author Not Committed Yet/{if (a && a !~ /author Not Committed Yet/) print a} {a=$0}' |
awk '{print $3}') ; do
if (( prev_line > -1 )) ; then
if (( "$n" > (prev_line + 1) )) ; then
if (( (prev_line - range_start) > 1 )) ; then
echo -n "$range_start-$prev_line,"
else
echo -n "$range_start,$prev_line,"
fi
range_start=$n
fi
else
range_start=$n
fi
prev_line=$n
done
if (( "$range_start" != "$prev_line" )) ; then
echo "$range_start-$prev_line"
else
echo "$range_start"
fi
And it ends up looking like this:
views.py:
403,404,533-538,546-548,550-552,554-559,565-567,580-582
It does great.. i need the exact same output using cvs.. Is there any way to get similar output..

bitwise XOR a string in Bash

I am trying to accomplish a work in Bash scripting. I have a string which i want to XOR with my key.
#!/bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
teststring="abcdefghijklmnopqr"
Now how do i XOR the value of teststring and store it in a variable using bash?
Any help will be appreciated.
Basically i am trying to duplicate the result of follwing VB Script:
Function XOREncryption(CodeKey, DataIn)
Dim lonDataPtr
Dim strDataOut
Dim temp
Dim tempstring
Dim intXOrValue1
Dim intXOrValue2
For lonDataPtr = 1 To Len(DataIn) Step 1
'The first value to be XOr-ed comes from the data to be encrypted
intXOrValue1 = Asc(Mid(DataIn, lonDataPtr, 1))
'The second value comes from the code key
intXOrValue2 = Asc(Mid(CodeKey, ((lonDataPtr Mod Len(CodeKey)) + 1), 1))
temp = (intXOrValue1 Xor intXOrValue2)
tempstring = Hex(temp)
If Len(tempstring) = 1 Then tempstring = "0" & tempstring
strDataOut = strDataOut + tempstring
Next
XOREncryption = strDataOut
End Function
With the help of these hints i wrote this quickly script to complete Pedro's answer:
#!/bin/bash
function ascii2dec
{
RES=""
for i in `echo $1 | sed "s/./& /g"`
do
RES="$RES `printf \"%d\" \"'$i\"`"
done
echo $RES
}
function dec2ascii
{
RES=""
for i in $*
do
RES="$RES`printf \\\\$(printf '%03o' $i)`"
done
echo $RES
}
function xor
{
KEY=$1
shift
RES=""
for i in $*
do
RES="$RES $(($i ^$KEY))"
done
echo $RES
}
KEY=127
TESTSTRING="abcdefghijklmnopqr"
echo "Original String: $TESTSTRING"
STR_DATA=`ascii2dec "$TESTSTRING"`
echo "Original String Data: $STR_DATA"
XORED_DATA=`xor $KEY $STR_DATA`
echo "XOR-ed Data: $XORED_DATA"
RESTORED_DATA=`xor $KEY $XORED_DATA`
echo "Restored Data: $RESTORED_DATA"
RESTORED_STR=`dec2ascii $RESTORED_DATA`
echo "Restored String: $RESTORED_STR"
Result:
iMac:Desktop fer$ bash test.sh
Original String: abcdefghijklmnopqr
Original String Data: 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
XOR-ed Data: 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13
Restored Data: 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
Restored String: abcdefghijklmnopqr
If you decide to go for Perl one-liner, here is what I came up with
perl -e '#a=split("", $ARGV[0]); #b=split("", $ARGV[1]); print unpack "H2", chr(ord(shift #a)^ord(shift #b)) while #a; print "\n"' aab aaa
zip function in Perl 6 would do a better job...
yet another answer
function xenc {
local data=$1 key=$2
local _data _key ndata nkey count i _res
_data=($(eval printf "'%d '" $(printf "%s" "$data" | sed -e '$!N;${s/./"'"'"'&" /g;s/""/\\&/g}')))
_key=($(eval printf "'%d '" $(printf "%s" "$key" | sed '$!N;${s/./"'"'"'&" /g;s/""/\\&/g}')))
ndata=${#_data[#]} nkey=${#_key[#]}
(( count = ndata < nkey ? nkey : ndata ))
for ((i = 0; i < count; i++)); do
(( _res[i] = ${_data[i]:-0} ^ ${_key[i%nkey]:-0} ))
done
printf "\\\\\\%o" "${_res[#]}" | xargs printf
}
res=$(xenc abcdefghijklmnopqrstuvwxyz FLqFb8LU0TY)
xenc "$res" FLqFb8LU0TY
Bitwise exclusive-OR in BASH requires both operands to be numeric. Since there's no built-in way of getting the ordinal (ASCII) value of a character in bash, you'll need to use, say, Perl, to get that value.
Edit: as noted below, ord works on the first character of a string only.
let a=`perl -e 'print ord $_ for split //, $ARGV[0]' string`^123; echo $a
Of course, once you're in Perl, you might as well do it all there:
let a=`perl -e '$ordinal .= ord $_ for split //, $ARGV[0]; print $ordinal ^ $ARGV[1]' string 123`
Edit: it turns out you can grab the ordinal value of a string in BASH using printf. Simply prefix the string with '.
printf "%d" "'string"
So, in BASH only:
let a=$(printf "%d" "'string")^123; echo $a
The most similar transformation of only the function to bash would be:
(# means comment):
# Function XOREncryption(CodeKey, DataIn)
XOREncryption(){
local CodeKey=$1
local DataIn=$2
# Dim lonDataPtr strDataOut temp tempstring intXOrValue1 intXOrValue2
local lonDataPtr strDataOut temp tempstring intXOrValue1 intXOrValue2
# For lonDataPtr = 1 To Len(DataIn) Step 1
for (( lonDataPtr=0; lonDataPtr < ${#DataIn}; lonDataPtr++ )); do
#The first value to be XOr-ed comes from the data to be encrypted
# intXOrValue1 = Asc(Mid(DataIn, lonDataPtr, 1))
intXOrValue1=$( toAsc "${DataIn:$lonDataPtr:1}" )
echo "val1=$intXOrValue1 and=<${DataIn:$lonDataPtr:1}> and $(toAsc "${DataIn:$lonDataPtr:1}")"
#The second value comes from the code key
echo "Ptr=$lonDataPtr Mod=<$(( lonDataPtr % ${#CodeKey} ))>"
# intXOrValue2 = Asc(Mid(CodeKey, ((lonDataPtr Mod Len(CodeKey)) + 1), 1))
intXOrValue2=$( toAsc "${CodeKey:$(( lonDataPtr % ${#CodeKey} )):1}" )
echo "val1=$intXOrValue1 val2=<${CodeKey:$(( lonDataPtr % ${#CodeKey} )):1}> and |$intXOrValue2|"
# temp = (intXOrValue1 Xor intXOrValue2)
temp=$(( intXOrValue1 ^ intXOrValue2 ))
echo "temp=$temp"
# tempstring = Hex(temp)
tempstring=$(printf '%02x' "$temp")
echo "tempstring=$tempstring"
# strDataOut = strDataOut + tempstring
strDataOut+=$tempstring
echo
# Next
done
# XOREncryption = strDataOut
printf '%s\n' "$strDataOut"
# End Function
}
Removing the comments, and cleaning the code:
#!/bin/bash
Asc() { printf '%d' "'$1"; }
XOREncryption(){
local key=$1 DataIn=$2
local ptr DataOut val1 val2
for (( ptr=0; ptr < ${#DataIn}; ptr++ )); do
val1=$( Asc "${DataIn:$ptr:1}" )
val2=$( Asc "${key:$(( ptr % ${#key} )):1}" )
DataOut+=$(printf '%02x' "$(( val1 ^ val2 ))")
done
printf '%s\n' "$DataOut"
}
CodeKey="$1"
teststring="$2"
XOREncryption "$CodeKey" "$teststring"
Running it:
$ ./script.sh "123456789" "abcdefghijklmnopqr"
5050505050505050505b595f595b5947494b
woks in busybox(the paste could not receive two streams), also made the key to repeat
#!/bin/sh
numitems() { i=0;while read ITEM; do i=$(( $i + 1 )) ; done; echo $i; }
starmap() { while read ITEM; do $1 $ITEM; done; }
ord() { printf '%d\n' "'$1"; }
chr() { printf \\$(printf '%03o' $1); }
split_chars() { echo -n "$1" | sed 's/./&\n/g'; }
xor() { echo $(($1 ^ $2)); }
map_ord() { split_chars "$1" | starmap ord; }
encrypt()
{
KEY=$1;STR=$2;
while [ ${#KEY} -lt ${#STR} ]; do KEY="$KEY$KEY"; done; #make key longer then str
[ -e /tmp/paste_col1 ] && rm -rf /tmp/paste_col1
[ -e /tmp/paste_col1t ] && rm -rf /tmp/paste_col1t
[ -e /tmp/paste_col2 ] && rm -rf /tmp/paste_col2
map_ord "$KEY">/tmp/paste_col1t
map_ord "$STR">/tmp/paste_col2
head -n `wc -l /tmp/paste_col2 |sed -r 's|^([0-9]+)\s.*|\1|'` /tmp/paste_col1t>/tmp/paste_col1 #trim lines
[ -e /tmp/paste_col1t ] && rm -rf /tmp/paste_col1t
paste /tmp/paste_col1 /tmp/paste_col2 | starmap xor | starmap chr
[ -e /tmp/paste_col1 ] && rm -rf /tmp/paste_col1
[ -e /tmp/paste_col2 ] && rm -rf /tmp/paste_col2
echo
}
KEY="12345678"
TESTSTRING="abcdefghasdfasdfasfdas"
encrypt "$KEY" "$TESTSTRING"
ENC="`encrypt \"$KEY\" \"$TESTSTRING\"`"
encrypt "$KEY" "$ENC" # we should get $TESTSTRING again