Header

Header

Thursday, May 30, 2019

Converting Python Caesar Cipher to Go Language Part 6

In this post the entire Caesar Cipher program will be listed:

 // Caesar Cipher  
 // Ported from https://inventwithpython.com/chapter14.html  
 package main  
 import (  
      "bufio"  
      "fmt"  
      "os"  
      "strconv"  
      "strings"  
      "unicode"  
 )  
 // declare variables and constants  
 const maxKeySize = 26  
 var mode string  
 var message string  
 var key rune  
 // prompt for encrypt or decrypt mode  
 func getMode() string {  
      for {  
           fmt.Println("Do you wish to encrypt or decrypt or brute force a message?")  
           var mode string  
           fmt.Scanln(&mode)  
           mode = strings.ToLower(mode)  
           if strings.Contains("encrypt e decrypt d brute b", mode) {  
                return mode  
           }  
           fmt.Println("Enter either \"encrypt\" or \"e\" or \"decrypt\" or \"d\" or \"brute\" or \"b\".")  
      }  
 }  
 // get message to encrypt or decrypt  
 func getMessage() string {  
      reader := bufio.NewReader(os.Stdin)  
      // print the prompt  
      fmt.Println("Enter your message:")  
      // use new reader to grap message  
      input, _ := reader.ReadString('\n')  
      return input  
 }  
 // Get the key value for the cipher offset  
 func getKey() rune {  
      var key rune  
      for {  
           fmt.Printf("Enter the key number (1 - %d)", maxKeySize)  
           fmt.Scanln(&key)  
           if key >= 1 && key <= maxKeySize {  
                return key  
           }  
      }  
 }  
 func getTranslatedMessage(mode string, message string, key rune) string {  
      if mode[0:len(mode)] == "d" {  
           key = -key  
      }  
      translated := ""  
      for _, symbol := range message {  
           if unicode.IsLetter(symbol) {  
                num := symbol  
                num += key  
                if unicode.IsUpper(symbol) {  
                     if num > 90 { // "Z"  
                          num -= 26  
                     } else if num < 65 { // "A"  
                          num += 26  
                     }  
                } else if unicode.IsLower(symbol) {  
                     if num > 122 { // "z"  
                          num -= 26  
                     } else if num < 97 { // "a"  
                          num += 26  
                     }  
                }  
                translated += string(rune(num))  
           } else {  
                translated += string(rune(symbol))  
           }  
      }  
      return strings.TrimSpace(translated)  
 }  
 func main() {  
      mode = getMode()  
      message = getMessage()  
      if mode[0:len(mode)] != "b" {  
           key = getKey()  
      }  
      fmt.Println("Your translated text is:")  
      if mode[0:len(mode)] != "b" {  
           fmt.Println(getTranslatedMessage(mode, message, key))  
      } else {  
           for i := 1; i <= maxKeySize; i++ {  
                fmt.Println(strconv.Itoa(i) + ". " + getTranslatedMessage("decrypt", message, rune(i)))  
           }  
      }  
 }  

Converting Python Caesar Cipher to Go Language Part 5

In this post we will continue converting the Caesar Cipher Python program to Go Language.

Let us take a look at the main function:

 func main() {  
      mode = getMode()  
      message = getMessage()  
      if mode[0:len(mode)] != "b" {  
           key = getKey()  
      }  
      fmt.Println("Your translated text is:")  
      if mode[0:len(mode)] != "b" {  
           fmt.Println(getTranslatedMessage(mode, message, key))  
      } else {  
           for i := 1; i <= maxKeySize; i++ {  
                fmt.Println(strconv.Itoa(i) + ". " + getTranslatedMessage("decrypt", message, rune(i)))  
           }  
      }  
 }  

In the main function, everything comes together,  all previous defined functions are now put into place and called to perform the encrypt and decrypt functionality of the Caesar Cipher program.

Please refer to each earlier post for details on the functionality of each function.

We start out by calling the getMode() function and the results of the getMode() function are stored in the mode variable.  The getMode() function determines whether we encrypt, decrypt or brute force decrypt the stored message.

Next  the main() function calls the getMessage() function which stores the results to the message variable.  The getMessage() function captures the encrypted or un-encrypted message, typed into the console by the user.

The program then prints a message before the getTranslatedMessage() function is called informing the user with the string "Your translated text is".

 if mode[0:len(mode)] != "b" {  
           fmt.Println(getTranslatedMessage(mode, message, key))  

In the above if statement:  mode[0:len(mode)] is treated as a slice:  https://blog.golang.org/go-slices-usage-and-internals

Starting at the first index, strings are zero based in Go, till the end of the string, we are looking for any character other than "b".  If the condition evaluates to true we execute the getTranslatedMessage() function.

If mode contains either "b" or "brute" we loop through each key value to brute force the decryption.  Each translated message is printed on it's own line.

In the next post we will list the entire Caesar Cipher program.

Thursday, May 23, 2019

Converting Python Caesar Cipher to Go Language Part 4

In this post we will continue converting the Caesar Cipher Python program to Go Language.

Let us take a look at the next function:

 def getTranslatedMessage(mode, message, key):  
   if mode[0] == 'd':  
     key = -key  
   translated = ''  
   for symbol in message:  
     if symbol.isalpha():  
       num = ord(symbol)  
       num += key  
       if symbol.isupper():  
         if num > ord('Z'):  
           num -= 26  
         elif num < ord('A'):  
           num += 26  
       elif symbol.islower():  
         if num > ord('z'):  
           num -= 26  
         elif num < ord('a'):  
           num += 26  
       translated += chr(num)  
     else:  
       translated += symbol  
   return translated  

The getTranslatedMessage() function is the heart of the Caesar Cipher program.  The function loops through each character and shifts the character's ASCII value to a value specified by the key variable.

In order to accomplish this task each character must be converted to it's ASCII value, using the ord() method,  https://docs.python.org/2/library/functions.html#ord

The getTranslatedMessage() function takes into consideration if the character is uppercase or lowercase between A-Z or between a - z and converts according. 

If the number is not between A-Z or between a - z then the symbol is not converted, the symbol is just appended to the translated variable.

If the character is between A-Z or between a-z, the ASCII value is converted back into a character using the chr() function.   https://docs.python.org/2/library/functions.html

Let us now take a look at the Go language equivalent:

 func getTranslatedMessage(mode string, message string, key rune) string {  
      if mode[0:len(mode)] == "d" {  
           key = -key  
      }  
      translated := ""  
      for _, symbol := range message {  
           if unicode.IsLetter(symbol) {  
                num := symbol  
                num += key  
                if unicode.IsUpper(symbol) {  
                     if num > 90 { // "Z"  
                          num -= 26  
                     } else if num < 65 { // "A"  
                          num += 26  
                     }  
                } else if unicode.IsLower(symbol) {  
                     if num > 122 { // "z"  
                          num -= 26  
                     } else if num < 97 { // "a"  
                          num += 26  
                     }  
                }  
                translated += string(rune(num))  
           } else {  
                translated += string(rune(symbol))  
           }  
      }  
      return strings.TrimSpace(translated)  
 }  

Let us take a look at the first if statement:

 if mode[0:len(mode)] == "d" {   
       key = -key   
    }   

Here mode is a string that contains one of several answers, e or enabled, d or disabled or b or brute.
The if statement is checking the string as a slice, from the first character to the length of the mode string, (the end of the string).  https://blog.golang.org/go-slices-usage-and-internals

 for _, symbol := range message {   

Go supports a range clause in the for() loop,  http://www.golangprograms.com/for-range-loops.html
As mentioned before the "_" is used to tell the compiler to ignore the iterator.

The symbol variable is typed by the Go compiler to be a rune type, which is used to parse unicode character data and stored unicode ASCII.  Notice that there is no ord() function that is needed.

 if unicode.IsLetter(symbol) {   
         num := symbol   
         num += key   
         if unicode.IsUpper(symbol) {   
            if num &gt; 90 { // "Z"   
              num -= 26   
            } else if num &lt; 65 { // "A"   
              num += 26   
            }   
         } else if unicode.IsLower(symbol) {   
            if num &gt; 122 { // "z"   
              num -= 26   
            } else if num &lt; 97 { // "a"   
              num += 26   
            }   
         }   
         translated += string(rune(num))   
       } else {   
         translated += string(rune(symbol))   
       }   

There is alot going on in the above segment, that is different than Python,  let up review section by section:

Python uses the symbol.isalpha(), symbol.isupper() and symbol.islower() functions to check for alpha characters, check for uppercase and lowercase.  These functions are part of the core language package in Python.

In Go language the unicode package is used to accomplish the same tasks.  But instead of converting a character to an ASCII we can work directly in ASCII as a result of the rune data type.

 if unicode.IsLetter(symbol) {  
                num := symbol  
                num += key  
                if unicode.IsUpper(symbol) {  
                     if num > 90 { // "Z"  
                          num -= 26  
                     } else if num < 65 { // "A"  
                          num += 26  
                     }  
                } else if unicode.IsLower(symbol) {  
                     if num > 122 { // "z"  
                          num -= 26  
                     } else if num < 97 { // "a"  
                          num += 26  
                     }  
                }  
                translated += string(rune(num))  
           } else {  
                translated += string(rune(symbol))  
           }  

You can clearly see this in the if, else if statements.  The Go Program is comparing ASCII values instead of character values.

As a result the Go program must convert from the rune data type back to character format using the string() function.

Monday, May 13, 2019

Converting Python Caesar Cipher to Go Language Part 3

In this post we will continue converting the Caesar Cipher Python program to Go Language.

Let us take a look at the next function:

 def getKey():  
   key = 0  
   while True:  
     print('Enter the key number (1-%s)' % (MAX_KEY_SIZE))  
     key = int(input())  
     if (key >= 1 and key <= MAX_KEY_SIZE):  
       return key  

In this function Python uses the while True: construct.  The input() function is used to capture the
key offset and is converted to an int.  The next if statement does some validation to make sure the entered key is between a value of 1 and the Max_Key_Size.

Let us now look at the converted Go code:

 // Get the key value for the cipher offset  
 func getKey() rune {  
      var key rune  
      for {  
           fmt.Printf("Enter the key number (1 - %d)", maxKeySize)  
           fmt.Scanln(&key)  
           if key >= 1 && key <= maxKeySize {  
                return key  
           }  
      }  
 }  

The biggest noticeable change in this code snippet is the use of the rune datatype.  In Go the Rune data type is an alias for int32.  Rune data types are mapped to unicode values. So if you stored the character 'a' to a Rune data type, the value stored would be 97.

Go does not support a while construct, only the for construct so you can use the for construct without an iterator, conditional statement or increment statement, and you get the for True evaluation.

Since we are looking for a single int value we can use the fmt.Scanln() function. The if statement contains the same expression evaluation.


Sunday, May 12, 2019

Converting Python Caesar Cipher to Go Language Part 2

In this post we will continue converting the Caesar Cipher Python program to Go Language.

Let us take a look at the next function:

 def getMessage():  
   print('Enter your message:')  
   return input()  

In Python 3 you can use the input() function to capture console input to a variable.  The input() function has the following syntax:  input([prompt]).  Notice the prompt is an optional argument and is not used in the above code snippet.

The input() method reads a line from input (usually user), converts the line into a string by removing the trailing newline, and returns it.

Let us look at the converted Go code snippet:

 // get message to encrypt or decrypt  
 func getMessage() string {  
      reader := bufio.NewReader(os.Stdin)  
      // print the prompt  
      fmt.Println("Enter your message:")  
      // use new reader to grap message  
      input, _ := reader.ReadString('\n')  
      return input  
 }  

We cannot use any of the fmt.Scan() functions as white space, triggers the function to place the next alphanumeric characters into another variable.  In this situation we most likely want to capture a sentence of word separated by spaces.

In Go, one way to capture a sentence would be to use the reader.ReadString() function from the bufio package.  https://golang.org/pkg/bufio/

We again use the fmt.Println() function to prompt the user for input.

  input, _ := reader.ReadString('\n')   

Notice the input, _ :=  syntax.  The single "_" underscore character is a common operator in Go,  In this example the reader.ReadString() function can return more than one value.  In the case of many functions in Go they can return error information in additional to function results, in this case the entered string.

The single "_" underscore operator tells the Go compiler to ignore the second return value.

The := operator is a short cut declaration that lets the compiler determine the variable data type and assign the value to the variable.



Tuesday, May 7, 2019

Learning Go Language

When I want to learn a new language I usually take an existing program and port that program to the new language I am learning.  I discovered a Python program out on the web that is simple and that I have ported before.

The program is a take on the Caesar Cipher encrypt and decrypt program.  Here is the link:

https://inventwithpython.com/chapter14.html

It turns out that this is a great program to convert to GO Language.  There is some character to ASCII conversion involved and GO Language deals with this conversion differently.

I will post the entire GO program later in this series on the GO Language.

Lets take a look at some of the issues I had to deal with:

 def getMode():  
   while True:  
     print('Do you wish to encrypt or decrypt a message?')  
     mode = input().lower()  
     if mode in 'encrypt e decrypt d brute b'.split():  
       return mode  
     else:  
       print('Enter either "encrypt" or "e" or "decrypt" or "d" or "brute" or "b".')  

Now let's take a look at the converted GO function:

 func getMode() string {  
      for {  
           fmt.Println("Do you wish to encrypt or decrypt or brute force a message?")  
           var mode string  
           fmt.Scanln(&mode)  
           mode = strings.ToLower(mode)  
           if strings.Contains("encrypt e decrypt d brute b", mode) {  
                return mode  
           }  
           fmt.Println("Enter either \"encrypt\" or \"e\" or \"decrypt\" or \"d\" or \"brute\" or \"b\".")  
      }  
 }  

Notice that in the Go Language example the fmt.Scanln() is used.  The Scanln() function is used, in this example, to capture a single alphanumeric character or word without white space.  The fmt package supports several difference functions to provide console input.  These functions can be combined with format verbs to control how the data in read from the console.  Please refer to the documentation on the fmt package for more details:  https://golang.org/pkg/fmt/
  • The obvious is the function declaration between Python 3 and GO Language
  • GO Language only supports a variety of for statements
  • GO Language supports printing and console input using the "fmt" package
  • GO Language supports double quotes and backticks
  • The "fmt" package supports a variety of print and scan functions
  • GO is stronger typed than Python

 fmt.Scanln(&mode)  

Notice the use of the ampersand character before the mode variable.  Yes Go supports pointers and the ampersand operator is referred to as the "Address of" operator.
Python 3 supports the following syntax:

 if mode in 'encrypt e decrypt d brute b'.split():   

GO does not support in .split() statement
I was able to perform the same operation by using the strings.Contains() function in the "strings" package.

 if strings.Contains("encrypt e decrypt d brute b", mode) {   

Python 3 did not require importing of any packages for the Caesar Cipher program.

The GO program required the following packages.

 import (  
      "bufio"  
      "fmt"  
      "os"  
      "strconv"  
      "strings"  
      "unicode"  
 )  

We will continue more conversion comparisons of the Caesar Cipher program in the next post.

Monday, May 6, 2019

Hello

Starting a blog to cover some tips, tricks and share some various code projects I have worked on.
I have started learning GO Language, so I will be posting some tips and tricks on Go Language.

https://joepitz.blogspot.com

Thanks

Joe