Saturday, August 27, 2016

Package Crypto - SHA256 Hash Algorithm Example

The Go package crypto/sha256 produces hexadecimal cryptographic hash (digest) of a message. You can play with the examples shared here and check the output in Go Playground (links shared below corresponding code snippets).

Let us see a working example:

Click to play with the above code

Here we've successfully encrypted "My secret message" using SHA256.
Things to note:

%X  is used to print elements of a Slice in hexadecimal, i.e. base 16 with upper-case letters for A-F)

Question
  • What happens if you replace %X with %x?
Let us see the next example where we're comparing the two outputs and printing true or false using %t :

Here the output is false. Why? It's simply because the two messages are different.

Click to play with the above code

Here's an excellent article about password encryption and security.


Wednesday, April 6, 2016

Go Channels for Absolute Beginners

Read Concurrency Parallelism and Goroutines for Beginners  before you proceed further.

CodeRef# 1

package main

import "fmt"

func main() {
 
      fmt.Println("A message from main function")
 
      go fmt.Println("A message from goroutine")
  
}


What do you think is the Output of above code?

A message from main function

Play with the Above Code

In most of the cases you would get the above output. But there can be cases where you may get both the messages as output. Here we can conclude that the output of the above code is undefined

Why didn't it always print the second message from the goroutine? 

The func main() here is running in a single OS execution thread. Once the main() code has finished writing "A message from main function"  it doesn't wait for the other subroutine (called using the keyword go) to finish its task.

A quick fix solution that can fix this issue is to introduce a delay in the main(). Something like:

 CodeRef# 2

package main

import "fmt"
import "time"

func main() {
 
      fmt.Println("A message from main function")
      go fmt.Println("A message from goroutine")
      time.Sleep(1 * time.Second) 
}


Output  CodeRef# 2


A message from main function
A message from goroutine

It seems we've achieved what we expected out of that code snippet. Right?

Though we've got the expected result it is a good example of bad programming. Time based synchronization must be avoided as they are inefficient and might lead to ugly bugs. You never know if the process will take 1 second (as introduced in the above example) or more or less than 1 second. Also, the time of execution may differ on different machine configuration. Avoid it!

CodeRef# 3

package main

import "fmt"
import "runtime"

func main() {
 
      fmt.Println("A message from main function")
      go fmt.Println("A message from goroutine")
      runtime.Gosched() 
}

Output  CodeRef# 3

A message from main function
A message from goroutine

Play with CodeRef# 3

This looks like a better solution. Here Gosched() has switched the execution context so that the other goroutine can finish its task. Gosched() yields the processor, allowing other goroutines to run.

What are Channels?

Goroutines run concurrently as independent units and hence there must be some mechanism to synchronize the access to shared memory. This is essential to prevent deadlock like scenarios. Go has Channels to sync goroutines. 

 The Little Go Book by Karl Seguin describes channels as:

You can think Channel as a communication pipe between goroutines which is used to pass data. In other words, A goroutine that has data can pass it to another goroutine via a channel. The result is that, at any point in time, only one goroutine has access to the data.

Remember, a channel can only transmit data-items of one datatype.

Type of Channels
  • Unbuffered or Synchronous
  • Buffered or Asynchronous
Declaring & Allocating Memory to Channels


                               intC := make(chan int)          //default capacity = 0
                               strC := make(chan string, 3) // non-zero capacity

Channel Supports 2 operations SEND and RECEIVE 

                               Channel <- Data                     // SEND 'data' to a channel
                               msg :- <- Channel                  //RECEIVE a message & Assign it to a variable msg

                               r := make(<-chan bool)          // can only read from
                               w := make(chan<- []os.FileInfo) // can only write to

Note: The left arrow operator <- is used for both sending & receiving data. The arrow head of the operator points in the direction of data flow. The channel SEND & RECEIVE operations are Atomic i.e. they always complete without any interruption. 

 CodeRef# 4

package main

import (
 "fmt"
 "time"
)

func main() {

 ch := make(chan int)

 go iSend(ch)
 go iReceive(ch)
 time.Sleep(time.Second * 1)
}

func iSend(ch chan int) {
 ch <- 1
 ch <- 3
 ch <- 5
 ch <- 7

}

func iReceive(ch chan int) {
 var info int
 // infinite for loop, executes till 'ch' is empty
 for {
  info = <-ch
  fmt.Printf("%d ", info)
 }
}

Output  CodeRef# 4


1 3 5 7 

Play with the Code

CodeRef# 5

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"
import "time"

func main() {
 ch1 := make(chan int)
 go send(ch1)
 go receive(ch1)
 time.Sleep(time.Second * 1)
}

func send(ch chan int) {
 for i := 1; i < 7; i++ {
  ch <- i
 }
}

func receive(ch chan int) {
 for {
  fmt.Println(<-ch)
 }
}


Output  CodeRef# 5

1
2
3
4
5
6

Play the code here 


CodeRef# 6

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import "fmt"
import "time"

func main() {
 ch := make(chan int)
 go sendOdd(ch)
 go sendEven(ch)
 go receive(ch)
 time.Sleep(time.Second * 1)
}

//This func to generate only Odd numbers
func sendOdd(ch chan int) {
 for i := 1; i < 9; i++ {
  if i%2 != 0 {
   ch <- i
  }
 }
}

//This func to generate only Even numbers
func sendEven(ch chan int) {
 for i := 1; i < 9; i++ {
  if i%2 == 0 {
   ch <- i
  }
 }
}

//Recive & Print numbers
func receive(ch chan int) {
 for {
  v := <-ch
  fmt.Println(v)
 }
}

Play with the Code

Output  CodeRef# 6

1
2
4
6
8
3
5
7


The above code is self explanatory. Play around and you'll soon get the knack of it. Please share your views to improve this article.

References

http://guzalexander.com/2013/12/06/golang-channels-tutorial.html


Sunday, February 7, 2016

Find Number of CPU Cores in Your Machine

How many CPU cores does your machine have? 

Here's a screenshot of my machine. It's showing 4 physical cores & 8 Logical Processors.




Why Cores are Important?


More cores are usually associated with better performance. From Go 1.5 onward, by default, Go programs run with GOMAXPROCS set to the number of cores available; in prior releases it defaulted to 1. This will definitely improve the performance of Go programs.


Here's the code to find out number of CPU cores/Logical Processors in your machine. The function NumCPU() returns the number of logical CPUs usable by the current process.



package main

import (
 "fmt"
 "runtime"
)

func main() {

 cores := runtime.NumCPU()

 fmt.Printf("This machine has %d CPU cores. \n", cores)

}

Saturday, January 30, 2016

Go Code to Find GCD / HCF of Two or More Integers


In mathematics, the greatest common divisor (GCD) of two or more integers, when at least one of them is not zero, is the largest positive integer that divides the numbers without a remainder.
                                                                                                                                  --- src: Wikipedia

For example, the GCD of 20 and 25 is 5.

The GCD is also known as the: 
      • Greatest common factor (GCF), 
      • Highest common factor (HCF), 
      • Greatest common measure (GCM), 
      • Highest common divisor (HCD)

Prerequisites to understand the following code:
Code follows:

package main

import "fmt"

func main() {

 var n int
 var num int
 var result int

 fmt.Println("How many integers GCD do you want to calculate?")
 fmt.Scanf("%d\n", &n)
 fmt.Println("Enter space separated integers:")
 numList := map[int]int{}

 for i := 1; i <= n; i++ {
  fmt.Scanf("%d", &num)
  numList[i] = num
 }
 //This is the result for only 2 integers
 result = gcd(numList[1], numList[2])

 //for loop in case there're more than 2 ints
 for j := 3; j <= n; j++ {
  result = gcd(result, numList[j])
 }

 fmt.Println("The GCD/HCF of given integers is: ", result)
}

//Func to implement Euclid Algo
func gcd(x, y int) int {
 for y != 0 {
  x, y = y, x%y
 }
 return x
}

Output



Play with the above code

Please share your feedback for improvement of this code.

Monday, January 25, 2016

Check if a String is Palindrome

The best way to learn a new computer language is by solving puzzles, games & code challenges. It's so much fun apart from the satisfaction you get once you crack them! Solving puzzles can push your language skills to the next level apart from improving your problem solving skills. From my experience I can tell you that in the beginning they're in fact a tough-nut-to-crack but once you persist enough to solve a few of them... it's kinda addictive! Start with the simple ones... and don't quit! 

For impatient learners who don't like preaching:

Play with the code and see the results in your browser - Once this page is open, click run and follow the instructions.

Another post that might interest you:


Tip - Take loads of break while solving puzzles. Sometimes you might need to take a break for a whole day so that you can reset your thoughts into a different direction. Also, if you've solved a puzzle in a single sitting, it's not a puzzle in the first place :) 

In this post we'll see how to find if an input string is a palindrome or not using Golang.

What is a Palindrome?

A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward or forward.

Examples of Palindrome
      • Madam
      • Civic
      • Noon
      • Refer
      • Rotor
      • Level
      • Malayalam
      • 1230321
Problem# 1

Enter a string and find out if the string is a Palindrome or not.

Solution# 1


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
 "fmt"
 "strings"
)

func main() {

 var ip string
 fmt.Println("Enter string:")
 fmt.Scanf("%s\n", &ip)
 ip = strings.ToLower(ip)
 fmt.Println(isP(ip))
}
//Function to test if the string entered is a Palindrome
func isP(s string) string { mid := len(s) / 2 last := len(s) - 1 for i := 0; i < mid; i++ { if s[i] != s[last-i] { return "NO. It's not a Palimdrome." } } return "YES! You've entered a Palindrome" }


Now let us build an advanced version of the problem where we can see a practical usage of Slices.

Problem# 2

Enter fixed number of strings, each in a new line, and find out if they are palindrome or not.


Solution# 2

To understand this solution you must have working knowledge of Slices in Go Programming.


package main

import (
 "fmt"
 "strings"
)

func main() {
 var n int
 var ip string
 fmt.Println("How many strings you want to test?")
 fmt.Scanf("%d\n", &n)
 strSlice := make([]string, 0)
 for i := 0; i < n; i++ {

  fmt.Printf("Enter %d string\n", i+1)
  fmt.Scanf("%s\n", &ip)
  ip := strings.ToLower(ip)
  strSlice = append(strSlice, ip)
 }
 for _, v := range strSlice {
  fmt.Println(isP(v))
 }
}

//Function to test if the string entered is a Palindrome
func isP(s string) string {

 mid := len(s) / 2
 last := len(s) - 1
 for i := 0; i < mid; i++ {
  if s[i] != s[last-i] {
   return "NO. " + s + " is Not a Palindrome"
  }
 }
 return "YES. " + s + " is a Palindrome"
}

Output# 2




Play with the above code

Exercise

If you find this interesting you can improve this code:

  1. To take care of the null/empty input strings.
  2. To return appropriate message if number of strings to test is entered zero.