LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Shell Script - Coded Alphabet (https://www.linuxquestions.org/questions/programming-9/shell-script-coded-alphabet-4175665747/)

Pinguino99 12-10-2019 01:52 PM

Shell Script - Coded Alphabet
 
Hi, everyone. :)
need help, I want to create a coded alphabet with specific values for each letter and character

ex:
# variables
A="@_banana"
a="99_Melon"
B="81_GRAPE"
b="22_strawberry"
@="9_love"
!="251_99"

the script codes the sentence
$ ./Encryptfruits -c "anything"

the script decodes the sentence
$ ./Encryptfruits -d "code"

would anyone have any examples? I searched on google but found nothing

Thank you all

astrogeek 12-10-2019 03:34 PM

Welcome to LQ and the Programming forum!

Please place your code and data snippets inside [CODE]...[/CODE] tags for better readability. You may type those yourself or click the "#" button in the edit controls.

The best way to obtain help from others is to show us what you have already done, and indicate what parts are giving you trouble. If this is a homework problem then you will only benefit if you try to work it out yourself.

The problem as stated is not too difficult, and as it should be a shell script we may assume bash and I would suggest that you begin with bash arrays. The bash man page is an excellent resource for that, and you will find many online references, such as this, and the section on arrays here.

See what you can figure out and let us know where you need help!

Good luck!

dugan 12-10-2019 03:37 PM

Not sure what this is for (just fun?), but you already know about rot13, right?

danielbmartin 12-10-2019 04:59 PM

Quote:

Originally Posted by Pinguino99 (Post 6066564)
... I want to create a coded alphabet with specific values for each letter and character ...

You have described a "one-to-many" substitution. The Linux command sed can do this.


Build a Pattern file of this form ...
Code:

s/A/@_banana/g
s/a/99_Melon/g
s/B/81_GRAPE/g
s/b/22_strawberry/g
s/@/9_love/g
s/!/251_99/g

With this InFile ...
Code:

apple banana cherry
date fig
grape kiwi lemon

... this sed ...
Code:

sed -f $PatFile $InFile >$OutFile
... produced this OutFile ...
Code:

99_Melonpple 22_strawberry99_Melonn99_Melonn99_Melon cherry
d99_Melonte fig
gr99_Melonpe kiwi lemon

Daniel B. Martin

.

Turbocapitalist 12-10-2019 10:11 PM

This is also quite fast in perl. Build a table.

Code:

my %a = (
    'A'=>'@_banana',
    'a'=>'99_Melon',

Then substitute:

Code:

s/(.)/$a{$1}/eg;
The substitution should probably be in a loop so you can fetch each word. Substitution ciphers can be broken just by looking at them usually.

See "man perlre", "man perlretut", and "man perldata" for starters.

What have you tried so far and where are you stuck? Post your code in whatever language between [code] ... [/code] tags and we'll be able to help.

Pinguino99 12-10-2019 11:31 PM

Code:


#! /bin/bash
declare -A crypt=(
    [A]="@_banana"
    [a]="99_melon"
    [B]="AZ_GRAPE"
    [b]="!!_stars"
    [C]="81_xxxxx"
    [c]="computer"
    [' ']="111_space"
    ['!']="life_9900"
)

encode () {
    local word=$1
    for ((i=0; i<${#word}; ++i)) ; do
        local char=${word:$i:1}
        printf %s' ' ${crypt[$char]}
    done
    printf '\n'
}

declare -A decrypt
for char in "${!crypt[@]}" ; do
    key=${crypt[$char]}
    decrypt[$key]=$char
done

decode () {
    local word=$1
    while [[ $word ]] ; do
        local code
        for code in "${!decrypt[@]}"; do
            if [[ $word == "$code"* ]] ; then
                printf %s "${decrypt[$code]}"
                word=${word#"$code"}
            fi
        done
    done
    printf '\n'
}

encode 'Abc!'

Code:

Output: @_banana !!_stars computer life_9900
each letter has been set to 8 characters in the array
I was wondering how do I do the reverse process
ex:

Code:

decode '@_banana !!_stars computer life_9900'
Code:

Output: Abc!

pan64 12-11-2019 01:01 AM

the revers process should do almost the same, just you need to use the decrypt array.
take first 8 chars, convert, remove from input and repeat.

grail 12-11-2019 03:15 AM

As some solutions have been provided, thought I would have a go in Ruby :)
Code:

#!/usr/bin/env ruby

cipher = { "A" => "@_banana",
          "a" => "99_melon",
          "B" => "AZ_GRAPE",
          "b" => "!!_stars",
          "C" => "81_xxxxx",
          "c" => "computer",
          " " => "111_space",
          "!" => "life_9900"
}

unless ARGV.size >= 2
  puts "Must have at least 2 arguments"
  exit
end

phrase = ARGV[1..-1]

case ARGV[0]
when '-e'
  type = 'encrypt'
  phrase = phrase.join(' ')
  joiner = ' '
when '-d'
  type = 'decrypt'
else
  puts 'Switch must be either -e or -d'
  exit
end

out = []

if type == 'encrypt'
  phrase.split(//).each{ |c| out << (cipher[c] || '#no key#') }
else
  phrase.each{ |word| out << (cipher.key(word) || '#no value#') }
end

puts out.join(joiner)

I am sure there is more checking which could be done or some edge cases, but it solves the problem with the given information :)

Pinguino99 12-11-2019 05:04 AM

I need it to be in shell script, awk, perl, I don't know how to make the array identify one every 8 characters to crack the code

Pinguino99 12-11-2019 05:17 AM

Quote:

Originally Posted by pan64 (Post 6066730)
the revers process should do almost the same, just you need to use the decrypt array.
take first 8 chars, convert, remove from input and repeat.

I'm trying to do that but I don't know how,

pan64 12-11-2019 06:18 AM

so post what did you try and we can help you to correct it. How did you make what you posted in #6?

Pinguino99 12-11-2019 07:32 AM

I'm trying
 
Code:

#! /bin/bash
declare -A crypt=(
    ['@_banana']="A"
    ['99_melon']="a"
    ['AZ_GRAPE']="B"
    ['!!_stars']="b"
    ['81_xxxxxx']="C"
    ['computer']="c"
    ['111_space']=' '
    ['life_9900']='!'
)

encode () {
    local word=$1
    for ((i=0; i<${#word}; ++i)) ; do
        local char=${word:$i:1}
        printf %s' ' ${crypt[$char]}
    done
    printf '\n'
}

declare -A decrypt
for char in "${!crypt[@]}" ; do
    key=${crypt[$char]}
    decrypt[$key]=$char
done

decode () {
    local word=$1
    while [[ $word ]] ; do
        local code
        for code in "${!decrypt[@]}"; do
            if [[ $word == "$code"* ]] ; then
                printf %s "${decrypt[$code]}"
                word=${word#"$code"}
            fi
        done
    done
    printf '\n'
}

encode '@_banana!!_starscomputerlife_9900'

Code:

Output:
I just tried to change the order but it doesn't work :(
i'm learning shell script, sorry for not understanding very well

pan64 12-11-2019 08:32 AM

first, you need to keep the original crypt and decrypt arrays, that was ok, no need to change.
Code:

# to get the first 8 chars use:
${word:1:8}
# to decrypt use
${decrypt[${word:1:8}]} # and check if that exists
# to cut the first 8 chars
word="${word:9}"


Pinguino99 12-11-2019 08:58 AM

Quote:

Originally Posted by pan64 (Post 6066828)
first, you need to keep the original crypt and decrypt arrays, that was ok, no need to change.
Code:

# to get the first 8 chars use:
${word:1:8}
# to decrypt use
${decrypt[${word:1:8}]} # and check if that exists
# to cut the first 8 chars
word="${word:9}"


which lines should I specifically change?

Code:

    1        #! /bin/bash
    2        declare -A decrypt=(
    3            ['@_banana']="A"
    4            ['99_melon']="a"
    5            ['AZ_GRAPE']="B"
    6            ['!!_stars']="b"
    7            ['81_xxxxxx']="C"
    8            ['computer']="c"
    9            ['111_space']=' '
    10            ['life_9900']='!'
    11        )
     
    12        encode () {
    13            local word=$1
    14            for ((i=0; i<${#word}; ++i)) ; do
    15                local char=${word:1:8}      #${word:$i:1}
    16                printf %s' ' ${crypt[$char]}
    17            done
    18            printf '\n'
    19        }
     
    20        declare -A decrypt
    21        for char in "${!crypt[@]}" ; do
    22            key=${crypt[$char]}
    23            decrypt[$key]=$char
    24        done
     
    25        decode () {
    26            local word="${word:9}
    27            while [[ $word ]] ; do
    28                local code
    29                for code in "${!decrypt[@]}"; do
    30                    if [[ $word == "$code"* ]] ; then
    31                        printf %s "${decrypt[$code]}"
    32                        word=${word#"$code"}
    33                    fi
    34                done
    35            done
    36            printf '\n'
    37        }
     
    38        encode '@_banana!!_starscomputerlife_9900'


Pinguino99 12-11-2019 12:47 PM

Code:

#! /bin/bash
declare -A decrypt=(
    ['@_banana']="A"
    ['99_melon']="a"
    ['AZ_GRAPE']="B"
    ['!!_stars']="b"
    ['81_xxxxxx']="C"
    ['computer']="c"
    ['111_space']=' '
    ['life_9900']='!'
)

encode () {
    local word=$1
    for ((i=0; i<${#word}; ++i)) ; do
        local char=${word:1:8}
        printf %s' ' ${decrypt[$char]}
    done
    printf '\n'
}

declare -A decrypt
for char in "${!decrypt[@]}" ; do
    key=${decrypt[$char]}
    decrypt[$key]=$char
done

decode () {
    local word=$1
    while [[ $word ]] ; do
        local code
        for code in "${!decrypt[@]}"; do
            if [[ $word == "$code"* ]] ; then
                printf %s "${decrypt[$code]}"
                word=${word#"$code"}
            fi
        done
    done
    printf '\n'
}

encode '@_banana!!_starscomputerlife_9900i'

I tried it and it didn't work


All times are GMT -5. The time now is 12:56 PM.