Sameeksha Medewar | 29 Mar, 2023

Download Golang Cheat Sheet PDF for Quick References


Go programming language is an open-source, compiled, and statistically typed programming language. Designed by Robert Griesemer, Rob Pike, and Ken Thompson, Google introduced Go or Golang in 2007 to increase programmer productivity. These designers created a language that incorporates the features of the following existing programming languages:

  • Runtime efficiency and static typing like C.
  • Readability and usability like Python and JavaScript.

This language has gained popularity because the Go language syntax is simple, accessible, and efficient, making it one of the best programming languages to secure a job. But you might not remember every single Golang function by heart. That’s why we created this Golang cheat sheet – your easy reference for Golang syntax and much more.

Click here to download our Golang Cheat Sheet PDF.

Golang Cheat Sheet

Before hopping directly into our Go cheat sheet, let’s cover Go set-up and installation.

How to Set Up and Install Go

First, you need to download the Go Archive. The following table highlights the available archives for each system:

OS Archive Name
Windows go1.14.windows-amd64.msi
Linux go1.14.linux-amd64.tar.gz
Mac go1.14.darwin-amd64-osx10.8.pkg
FreeBSD go1.14.freebsd-amd64.tar.gz

After downloading the appropriate archive, extract it to the /usr/local. Later, create a folder named “Go” in that folder. You can run the following command from your command prompt (cmd).

mkdir /usr/local/Go
tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
brew install go

Now, you must add the path variable /usr/local/go/bin to the environment variable. The following table highlights the path variable for various operating systems:

OS Output
Linux export PATH = $PATH:/usr/local/go/bin
Mac export PATH = $PATH:/usr/local/go/bin
FreeBSD export PATH = $PATH:/usr/local/go/bin

Execute the following command in cmd to add the path variables:

// add to ~/.bash_profile
export GOPATH="$HOME/Go"
export PATH="/usr/local/bin:$PATH:$GOPATH/bin"

Create a Sample File in Windows

Here, we can create a test.go file in C:\>Go_WorkSpace.

package main

import"fmt"

funcmain() {
fmt.Println("Hello")
}

To execute the test, run the following command from cmd:

C:\Go_WorkSpace>go run test.go

You will get the output:

Hello

Basic Go Syntax

Now let’s get started with some basic syntax for Golang.

package main

import "fmt"

func main() {
    fmt.Println("Hello World")
}

Where: Package is a collection of the files and code. Make sure to add the “package main” at the top of your every Go program. Fmt is a package available in the Go language’s standard library. It helps you format strings and print messages to the command line. One of the methods included is the “println” that prints the line. As per the above example, we have used it to print the “Hello World” on cmd. “Main” function holds the code that will perform the task for you. To run this code, type “go run main.go,” and hit enter. You can give any name to your Go program.

Operators

Every programming language comes with operators, which allows you to perform arithmetic, logical, bitwise, comparison, and other functions. Let's walk through Go operators, along with their descriptions and examples.

Arithmetic Operators

Arithmetic operators perform mathematical operations on operands.

Operator Description Example
+ Adds two operands A + B gives 30
- Subtracts second operand from the first A - B gives -10
* Multiplies both operands A * B gives 200
/ Divides the numerator by the denominator. B / A gives 2
% Modulus operator; gives the remainder after an integer division. B % A gives 0
++ Increment operator. increases the integer value by one. A++ gives 11
-- Decrement operator decreases the integer value by one. A-- gives 9

Relational Operators

You can use relational operators to compare two values.

Operator Description Example
== Checks if the values of two operands are equal or not; if yes, the condition becomes true. (A == B) is not true.
!= Checks if the values of two operands are equal or not; if the values are not equal, then the condition becomes true. (A != B) is true.
> Checks if the left operand value is greater than the value of right operand; if yes, the condition becomes true. (A > B) is not true.
< Checks if the left operand value is less than the value of the right operand; if yes, the condition becomes true. (A < B) is true.
>= Checks if the left operand value is greater than or equal to the value of the right operand; if yes, the condition becomes true. (A >= B) is not true.
<= It checks if the left operand value is less than or equal to right operand value; if yes, the condition becomes true. (A <= B) is true.

Logical Operators

You can use logical operators to combine two or more conditions.

Operator Description Example
&& Called Logical AND operator. If both the operands are non-zero, the condition becomes true. (A && B) is false.
|| Called Logical OR Operator. If any of the two operands is non-zero, the condition becomes true. (A || B) is true.
! Called Logical NOT Operator. Used to reverse the logical state of its operand. If a condition is true, then the Logical NOT operator will make it false. !(A && B) is true.

Bitwise Operators

These perform bit-by-bit operations. The truth tables for &, |, and ^ are as follows:

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
Operator Description Example
& Binary AND Operator copies a bit to the result if it exists in both operands. (A & B) will give 12, which is 0000 1100
| Binary OR Operator copies a bit if it exists in either operand. (A | B) will give 61, which is 0011 1101
^ Binary XOR Operator copies the bit if it is set in one operand but not both. (A ^ B) will give 49, which is 0011 0001
<< Binary Left Shift Operator. The left operand's value is moved left by the number of bits specified by the right operand. A << 2 will give 240 which is 1111 0000
>> Binary Right Shift Operator. The left operand's value is moved right by the number of bits specified by the right operand. A >> 2 will give 15 which is 0000 1111

Assignment Operators

Assignment operators help you assign values to variables.

Operator Description Example
+ Simple assignment operator, Assigns values from right side operands to left side operand C = A + B will assign value of A + B into C
+- Add AND assignment operator, Adds right operand to the left operand and assign the result to left operand C += A is equivalent to C = C + A
-= Subtract AND assignment operator, It subtracts right operand from the left operand and assigns the result to left operand C -= A is equivalent to C = C - A
*= Multiply AND assignment operator, It multiplies right operand with left operand and assigns the result to left operand C *= A is equivalent to C = C * A
/= Divide AND assignment operator. It divides left operand with the right operand and assigns the result to left operand C /= A is equivalent to C = C / A
%= Modulus AND assignment operator. It takes modulus using two operands and assign the result to left operand C %= A is equivalent to C = C % A
<<= Left shift AND assignment operator C <<= 2 is same as C = C << 2
>>= Right shift AND assignment operator C >>= 2 is same as C = C >> 2
&= Bitwise AND assignment operator C &= 2 is same as C = C & 2
^= bitwise exclusive OR and assignment operator C ^= 2 is same as C = C ^ 2
|= bitwise inclusive OR and assignment operator C |= 2 is same as C = C | 2

Miscellaneous Operators

Operator Description Example
& Returns the address of a variable. &a; returns the actual address of the variable ‘a’.
* Pointer to a variable. *a; provides a pointer to a variable.

Operators Precedence

Category Operator Associativity
Postfix () [] -> . ++ - - Left to right
Unary + - ! ~ ++ - - (type)* & sizeof Right to left
Multiplicative * / % Left to right
Additive + - Left to right
Shift << >> Left to right
Relational < <= > >= Left to right
Equality == != Left to right
Bitwise AND & Left to right
Bitwise XOR ^ Left to right
Bitwise OR | Left to right
Logical AND && Left to right
Logical OR || Left to right
Assignment = += -= *= /= %=>>= <<= &= ^= |= Right to left
Comma , Left to right

Data Types

Basic Data Types

Types Description
Boolean types They are boolean types and consists of the two predefined constants: (a) true (b) false
Numeric types They are arithmetic types and represent a) integer types or b) floating-point values throughout the program.
String types A string type represents the set of string values. Its value is a sequence of bytes. Strings are immutable types that, once created, cannot be changed. The predeclared string type is a string.
Derived types These include (a) Pointer types, (b) Array types, (c) Structure types, (d) Union types and (e) Function types f) Slice types g) Interface types h) Map types i) Channel Types

Integer Types

uint8 Unsigned 8-bit integers (0 to 255)
uint16 Unsigned 16-bit integers (0 to 65535)
uint32 Unsigned 32-bit integers (0 to 4294967295)
uint64 Unsigned 64-bit integers (0 to 18446744073709551615)
int8 Signed 8-bit integers (-128 to 127)
int16 Signed 16-bit integers (-32768 to 32767)
int32 Signed 32-bit integers (-2147483648 to 2147483647)
int64 Signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

Floating-Point Types

float32 IEEE-754 32-bit floating-point numbers
float64 IEEE-754 64-bit floating-point numbers
complex64 Complex numbers with float32 real and imaginary parts
complex128 Complex numbers with float64 real and imaginary parts

Other Data Types

Type Description
byte same as uint8
rune same as int32
uint 32 or 64 bits
int same size as uint
uintptr an unsigned integer to store the uninterpreted bits of a pointer value

Variables

A variable is a name given to the storage area consistently altered during program execution. Golang supports the following types of variables:

Type Description
byte Typically a single octet(one byte). This is a byte type.
int The most natural size of integer for the machine.
float32 A single-precision floating-point value.

Declaring a Go Variable

  • Using var keyword:

var variable_name type = expression

  • Using short variable declaration:

variable_name:= expression

Example

...
funcmain() {
var age int
age = 70
fmt.Printf("Quantity is %d\n", quantity)
}

// You can merge the var dedclaration and assignment to one
var age int = 70

// Or you can use shorthand variable declaration operator, :=, which
// can infer type
age := 70

Declaring Multiple Variables (using :=)

func main() {
    // As long as one of the variables is new, `:=` can be used.
    // However, you can't change the type of age. It was declared (implicitly)
    // as an integer and thus, can only be assigned integers.
    name, age := "Lemmy", 70
    fmt.Printf("%s's age is %d\n", name, age)
}

Constants

Constants, or literals, are fixed values that we cannot alter during program execution. Golang supports different types of constants, such as integer constant, floating constant, character constant, or string literal.

There are also enumeration constants Constants are used just like variables except you cannot change their value during program execution.

Declaring Constants Example:

package main

import "fmt"

const PI = 3.1412

func main() {
    const SC = "SC"
    fmt.Println("Hello", SC)

    fmt.Println("Happy", PI, "Day")

    const Correct= true
    fmt.Println( Correct)
}

Output:

Hello SC
Happy 3.14 Day
true

Integer Constant Examples

85 /* decimal */

0213 /* octal */

0x4b /* hexadecimal */

30 /* int */

30u /* unsigned int */

30l /* long */

30ul /* unsigned long */

212 /* Legal */

215u /* Legal */

0xFeeL /* Legal */

078 /* Illegal: 8 is not an octal digit */

032UU /* Illegal: cannot repeat a suffix */

Floating Type Constant Examples

3.14159 /* Legal */

314159E-5L /* Legal */

510E /* Illegal: incomplete exponent */

210f /* Illegal: no decimal or exponent */

.e55 /* Illegal: missing integer or fraction */

String Literals Examples

Syntax of string literal:

type _string struct {
    elements *byte // underlying bytes
    len      int   // number of bytes
}

Example:

"hello, SC"

"hello, \
SC"

"hello, " "S" "hello"

Const Keyword

const variable type = value;  //declaring 

Example:

package main

import "fmt"

func main() {
   const LEN int = 4
   const WID int = 5   
   var area int

   area = LEN * WID
   fmt.Printf("value of area : %d", area)   
}

Output

value of area : 20

Escape Sequence

Escape sequence Meaning
\\ \ character
\’ ‘ character
\” ” character
\? ? character
\a Alert or bell
\b Backspace
\f Form feed
\n Newline
\r Carriage return
\t Horizontal tab
\v Vertical tab
\ooo Octal number of one to three digits
\xhh . . . Hexadecimal number of one or more digits

Decision-Making Structures

The decision-making structures help programmers perform tasks based on the condition to be evaluated. If the specified condition is true, the code will run, or it will run alternate code mentioned within the program.

Golang supports the following types of decision making structure statements:

  • If
  • if..else
  • Nested if
  • Switch
  • Select

If Statement

If the condition specified is true, then only the block of code executes.

Syntax:

if(boolean_expression) {
   /* statement(s) will execute if the boolean expression is true */
}

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 15
 
   /* check the boolean condition using if statement */
   if( a < 20 ) {
      /* if condition is true then print the following */
      fmt.Printf("a is less than 20\n" )
   }
   fmt.Printf("value of a is : %d\n", a)
}

if..else Statement

If the specified condition holds true, the ‘if’ block executes. Otherwise, the ‘else’ block executes.

Syntax:

if(boolean_expression) {
   /* statement(s) will execute if the boolean expression is true */
} else {
   /* statement(s) will execute if the boolean expression is false */
}

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 100;
 
   /* check the boolean condition */
   if( a < 20 ) {
      /* if condition is true then print the following */
      fmt.Printf("a is less than 20\n" );
   } else {
      /* if condition is false then print the following */
      fmt.Printf("a is not less than 20\n" );
   }
   fmt.Printf("value of a is : %d\n", a);
}

Nested “If” Statement

The nested if statement implies one ‘if’ statement inside another.

Syntax:

if( boolean_expression 1) {
   /* Executes when the boolean expression 1 is true */
   if(boolean_expression 2) {
      /* Executes when the boolean expression 2 is true */
   }
}

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 100
   var b int = 200
 
   /* check the boolean condition */
   if( a == 100 ) {
      /* if condition is true then check the following */
      if( b == 200 )  {
         /* if condition is true then print the following */
         fmt.Printf("Value of a is 100 and b is 200\n" );
      }
   }
   fmt.Printf("Exact value of a is : %d\n", a );
   fmt.Printf("Exact value of b is : %d\n", b );
}

Switch Statement

A switch statement is a multi-way branch statement. You can specify multiple conditionals across many branches.

switch(boolean-expression or integral type){
   case boolean-expression or integral type :
      statement(s);      
   case boolean-expression or integral type :
      statement(s); 
   
   /* you can have any number of case statements */
   default : /* Optional */
      statement(s);
}

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var grade string = "B"
   var marks int = 90

   switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
   }
   switch {
      case grade == "A" :
         fmt.Printf("Excellent!\n" )     
      case grade == "B", grade == "C" :
         fmt.Printf("Well done\n" )      
      case grade == "D" :
         fmt.Printf("You passed\n" )      
      case grade == "F":
         fmt.Printf("Better try again\n" )
      default:
         fmt.Printf("Invalid grade\n" );
   }
   fmt.Printf("Your grade is  %s\n", grade );      
}

Select Statement

The select statement is analogous to the switch statement. However, here the case statement refers to communication.

Syntax:

select {
   case communication clause  :
      statement(s);      
   case communication clause  :
      statement(s); 
   /* you can have any number of case statements */
   default : /* Optional */
      statement(s);
}

Example:

package main

import "fmt"

func main() {
   var c1, c2, c3 chan int
   var i1, i2 int
   select {
      case i1 = <-c1:
         fmt.Printf("received ", i1, " from c1\n")
      case c2 <- i2:
         fmt.Printf("sent ", i2, " to c2\n")
      case i3, ok := (<-c3):  // same as: i3, ok := <-c3
         if ok {
            fmt.Printf("received ", i3, " from c3\n")
         } else {
            fmt.Printf("c3 is closed\n")
         }
      default:
         fmt.Printf("no communication\n")
   }    
}  

Loops

If you want to execute some part of the code several times, you can implement loops. Read on for more details about the loops Golang supports.

“for” Loop

When you need to execute a specific block of code for a particular number of times, you can use the ‘for’ loop.

Syntax:

for [condition |  ( init; condition; increment ) | Range] {
   statement(s);
}

Example:

package main

import "fmt"

func main() {
   var b int = 15
   var a int
   numbers := [6]int{1, 2, 3, 5} 

   /* for loop execution */
   for a := 0; a < 10; a++ {
      fmt.Printf("value of a: %d\n", a)
   }
   for a < b {
      a++
      fmt.Printf("value of a: %d\n", a)
   }
   for i,x:= range numbers {
      fmt.Printf("value of x = %d at %d\n", x,i)
   }   
}

Nested Loops

The nested loop implies the loops inside another loop.

Syntax:

for [condition |  ( init; condition; increment ) | Range] {
   for [condition |  ( init; condition; increment ) | Range] {
      statement(s);
   }
   statement(s);
}

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var i, j int

   for i = 2; i < 100; i++ {
      for j = 2; j <= (i/j); j++ {
         if(i%j==0) {
            break; // if factor found, not prime
         }
      }
      if(j > (i/j)) {
         fmt.Printf("%d is prime\n", i);
      }
   }  
}

Simple Range In For Loop

for i, j:= range rvariable{
   // statement..
}

Using for loop for Strings

A for loop can iterate over the Unicode code point for a string.

for index, chr:= range str{
     // Statement..
}

For Maps

A for loop can iterate over the key and value pairs of the map.

for key, value := range map { 
     // Statement.. 
}

For Channel

A for loop can iterate over the sequential values sent on a channel until it closes.

for item := range Chnl { 
     // statements..
}

Loop Control Statements

There are three loop control statements in Go:.

  • Break
  • Continue
  • Goto statement

Break

Whenever you use a break statement within a loop, the loop is immediately terminated and the program control resumes at the next statement following the loop.

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 10

   /* for loop execution */
   for a < 20 {
      fmt.Printf("value of a: %d\n", a);
      a++;
      if a > 15 {
         /* terminate the loop using break statement */
         break;
      }
   }
}

Go: The Complete Developer's Guide to Golang: 4-in-1

Continue

The continue statement works like a break statement; however, instead of performing a forced termination, a continue statement starts the next iteration of the loop, skipping any code in between.

But if you use “continue” with the “for” loop, it causes the conditional test and increment portions of the loop to execute.

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 10

   /* do loop execution */
   for a < 20 {
      if a == 15 {
         /* skip the iteration */
         a = a + 1;
         continue;
      }
      fmt.Printf("value of a: %d\n", a);
      a++;     
   }  
}

Goto Statement

This statement performs an unconditional jump from the goto to a labeled statement in the same function.

Example:

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 10

   /* do loop execution */
   LOOP: for a < 20 {
      if a == 15 {
         /* skip the iteration */
         a = a + 1
         goto LOOP
      }
      fmt.Printf("value of a: %d\n", a)
      a++     
   }  
}

Functions

As with any other object-oriented programming language, Golang allows you to create functions.

Syntax:

funcfunction_name( [parameter list] ) [return_types]
{
body of the function
}

Where:

  • func: To declare a function, you need to use the func keyword.
  • function_name: It specifies the name of the function and you need to call it using this name with proper arguments.
  • Parameter list: It defines the parameters used (if any) within the function, and these values are provided by the user during runtime. This value is referred to as an actual parameter or argument. The parameter list consists of the type, order, and number of the parameters.
  • return type: A function may return a list of values. The return_types defines the type of that returned value.
  • body of function: This is where you place the code to be executed.

Example:

func max(num1, num2 int) int {
   /* local variable declaration */
   result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

How to Call a Function

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 100
   var b int = 200
   var ret int

   /* calling a function to get max value */
   ret = max(a, b)

   fmt.Printf( "Max value is : %d\n", ret )
}

/* function returning the max between two numbers */
func max(num1, num2 int) int {
   /* local variable declaration */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

How to Return Multiple Values from a Function

package main

import "fmt"

func swap(x, y string) (string, string) {
   return y, x
}
func main() {
   a, b := swap("Mahesh", "Kumar")
   fmt.Println(a, b)
}

Function Arguments

Call by Value

The Go programming language uses the call by value method to pass arguments. This means that code within a function cannot alter the arguments used to call the function.

Example:

func swap(int x, int y) int {
   var temp int

   temp = x /* save the value of x */
   x = y    /* put y into x */
   y = temp /* put temp into y */

   return temp;
}
Call by Reference

This method copies the argument address into the formal parameter. Inside the function, the address is used to access the actual argument used in the call.

Example:

func swap(x *int, y *int) {
   var temp int
   temp = *x    /* save the value at address x */
   *x = *y      /* put y into x */
   *y = temp    /* put temp into y */
}

Introduction to Graphic Design

Scope

The scope defines the area in the program where the defined variable can be used. In Golang, you can declare variables with three scopes.

  • Local variables
  • Global variables
  • Formal variables

Local variables

These variables have scope within the function or code block where they have been declared. They cannot be accessed outside that code block.

Example:

package main

import "fmt"

func main() {
   /* local variable declaration */
   var a, b, c int 

   /* actual initialization */
   a = 10
   b = 20
   c = a + b

   fmt.Printf ("value of a = %d, b = %d and c = %d\n", a, b, c)
}

Global Variables

These variables are declared outside the function or code block and can be accessed from functions within the program.

Example:

package main

import "fmt"
 
/* global variable declaration */
var g int
 
func main() {
   /* local variable declaration */
   var a, b int

   /* actual initialization */
   a = 10
   b = 20
   g = a + b

   fmt.Printf("value of a = %d, b = %d and g = %d\n", a, b, g)
}

Formal Parameters

Formal parameters are treated as local variables within that function and they take preference over the global variables.

Example:

package main

import "fmt"
 
/* global variable declaration */
var a int = 20;
 
func main() {
   /* local variable declaration in main function */
   var a int = 10
   var b int = 20
   var c int = 0

   fmt.Printf("value of a in main() = %d\n",  a);
   c = sum( a, b);
   fmt.Printf("value of c in main() = %d\n",  c);
}
/* function to add two integers */
func sum(a, b int) int {
   fmt.Printf("value of a in sum() = %d\n",  a);
   fmt.Printf("value of b in sum() = %d\n",  b);

   return a + b;
}

Arrays

An array is a data structure that stores elements of the same data type. It has a fixed-length. All array elements are stored at contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element. For example, an array can store the marks of students in a specific subject.

Declaring an Array

Syntax: 

var variable_name [SIZE] variable_type

Example: 

var balance [10] float32

Initializing an Array

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

Accessing the Elements of an Array

float32 salary = balance[9]

Example:

package main

import "fmt"

func main() {
   var n [10]int /* n is an array of 10 integers */
   var i,j int

   /* initialize elements of array n to 0 */         
   for i = 0; i < 10; i++ {
      n[i] = i + 100 /* set element at location i to i + 100 */
   }
   
   /* output each array element's value */
   for j = 0; j < 10; j++ {
      fmt.Printf("Element[%d] = %d\n", j, n[j] )
   }
}

Pointers

Pointers are used to make complex tasks easier, such as call by reference, and cannot be performed without using pointers. As you know, every variable is a memory location having its address defined and that can be accessed using ampersand (&) operator. In short, a pointer is a variable that stores the address of another variable.

Syntax:

var var_name *var-type
var ip *int        /* pointer to an integer */
var fp *float32    /* pointer to a float */

Example:

package main
import "fmt"
func main() {
   var a int = 20   /* actual variable declaration */
   var ip *int      /* pointer variable declaration */

   ip = &a  /* store address of a in pointer variable*/

   fmt.Printf("Address of a variable: %x\n", &a  )

   /* address stored in pointer variable */
   fmt.Printf("Address stored in ip variable: %x\n", ip )

   /* access the value using the pointer */
   fmt.Printf("Value of *ip variable: %d\n", *ip )
}

Nil Pointers

package main
import "fmt"
func main() {
   var  ptr *int
   fmt.Printf("The value of ptr is : %x\n", ptr  )
}

Defer Keyword

You can create a deferred method, or function, or anonymous function by using the defer keyword.

  • // Function
defer func func_name(parameter_list Type)return_type{
// Code
}
  • // Method
defer func (receiver Type) method_name(parameter_list){
// Code
}

defer func (parameter_list)(return_type){
// code
}()

Structure (struct)

With structures, you can create user-defined data types with information about various data types. Unlike arrays, structures can store data items of different data types. For example, a structure can store the name, class, age, and marks of students of a specific class.

Syntax:

type struct_variable_type struct {
   member definition;
   member definition;
   ...
   member definition;
}

Accessing a Structure’s Members

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}
func main() {
   var Book1 Books    /* Declare Book1 of type Book */
   var Book2 Books    /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = "Go Programming"
   Book1.author = "Mahesh Kumar"
   Book1.subject = "Go Programming Tutorial"
   Book1.book_id = 6495407

   /* book 2 specification */
   Book2.title = "Telecom Billing"
   Book2.author = "Zara Ali"
   Book2.subject = "Telecom Billing Tutorial"
   Book2.book_id = 6495700
 
   /* print Book1 info */
   fmt.Printf( "Book 1 title : %s\n", Book1.title)
   fmt.Printf( "Book 1 author : %s\n", Book1.author)
   fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
   fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

   /* print Book2 info */
   fmt.Printf( "Book 2 title : %s\n", Book2.title)
   fmt.Printf( "Book 2 author : %s\n", Book2.author)
   fmt.Printf( "Book 2 subject : %s\n", Book2.subject)
   fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)
}

Pointers to Structure

var struct_pointer *Books
struct_pointer = &Book1;

Example:

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}
func main() {
   var Book1 Books   /* Declare Book1 of type Book */
   var Book2 Books   /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = "Go Programming"
   Book1.author = "Mahesh Kumar"
   Book1.subject = "Go Programming Tutorial"
   Book1.book_id = 6495407

   /* book 2 specification */
   Book2.title = "Telecom Billing"
   Book2.author = "Zara Ali"
   Book2.subject = "Telecom Billing Tutorial"
   Book2.book_id = 6495700
 
   /* print Book1 info */
   printBook(&Book1)

   /* print Book2 info */
   printBook(&Book2)
}
func printBook( book *Books ) {
   fmt.Printf( "Book title : %s\n", book.title);
   fmt.Printf( "Book author : %s\n", book.author);
   fmt.Printf( "Book subject : %s\n", book.subject);
   fmt.Printf( "Book book_id : %d\n", book.book_id);
}

Slice

Go Slice is an abstraction over Go Array. Go Array allows you to define variables to hold several data items of the same kind but it does not provide any inbuilt method to increase its size dynamically or get a sub-array of its own. But Slice in Go can overcome this problem.

Defining a Slice

var numbers []int /* a slice of unspecified size */
/* numbers == []int{0,0,0,0,0}*/
numbers = make([]int,5,5) /* a slice of length 5 and capacity 5*/

len() and cap() Function

The len() function returns the elements presents in the slice, whereas the cap() function returns the capacity of the slice.

package main

import "fmt"

func main() {
   var numbers = make([]int,3,5)
   printSlice(numbers)
}
func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

Nil Slice

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)
   
   if(numbers == nil){
      fmt.Printf("slice is nil")
   }
}
func printSlice(x []int){
   fmt.Printf("len = %d cap = %d slice = %v\n", len(x), cap(x),x)
}

append() and copy() Functions

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)
   
   /* append allows nil slice */
   numbers = append(numbers, 0)
   printSlice(numbers)
   
   /* add one element to slice*/
   numbers = append(numbers, 1)
   printSlice(numbers)
   
   /* add more than one element at a time*/
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)
   
   /* create a slice numbers1 with double the capacity of earlier slice*/
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)
   
   /* copy content of numbers to numbers1 */
   copy(numbers1,numbers)
   printSlice(numbers1)   
}
func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

Range

The range keyword is used in for loop to iterate over items of an array, slice, channel, or map. With array and slices, it returns the index of the item as integer. With maps, it returns the key of the next key-value pair.

Range expression 1st Value 2nd Value(Optional)
Array or slice a [n]E index i int a[i] E
String s string type index i int rune int
map m map[K]V key k K value m[k] V
channel c chan E element e E none

Example:

package main

import "fmt"

func main() {
   /* create a slice */
   numbers := []int{0,1,2,3,4,5,6,7,8} 
   
   /* print the numbers */
   for i:= range numbers {
      fmt.Println("Slice item",i,"is",numbers[i])
   }
   
   /* create a map*/
   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo"}
   
   /* print map using keys*/
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   
   /* print map using key-value*/
   for country,capital := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",capital)
   }
}

Maps

Golang offers another important data type called map, which maps unique keys to values. Here, a key is an object used to retrieve a value. You can store the value (key and value) in a Map object.

Defining a Map

Syntax:

/* declare a variable, by default map will be nil*/
var map_variable map[key_data_type]value_data_type

/* define the map as nil map can not be assigned any value*/
map_variable = make(map[key_data_type]value_data_type)

 

Example:

package main
import "fmt"
func main() {
   var countryCapitalMap map[string]string
   /* create a map*/
   countryCapitalMap = make(map[string]string)
   
   /* insert key-value pairs in the map*/
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "Rome"
   countryCapitalMap["Japan"] = "Tokyo"
   countryCapitalMap["India"] = "New Delhi"
   
   /* print map using keys*/
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   
   /* test if entry is present in the map or not*/
   capital, ok := countryCapitalMap["United States"]
   
   /* if ok is true, entry is present otherwise entry is absent*/
   if(ok){
      fmt.Println("Capital of United States is", capital)  
   } else {
      fmt.Println("Capital of United States is not present") 
   }
}

Delete() Function

package main
import "fmt"
func main() {   
   /* create a map*/
   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo","India":"New Delhi"}
   
   fmt.Println("Original map")   
   
   /* print map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   
   /* delete an entry */
   delete(countryCapitalMap,"France");
   fmt.Println("Entry for France is deleted")  
   
   fmt.Println("Updated map")   
   
   /* print map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
}

Recursion

Through the recursion process, you can repeat items and apply the same concept. When one function calls another function inside it, it is called a recursive function call.

Syntax:

func recursion() {
   recursion() /* function calls itself */
}
func main() {
   recursion()
}

Example (calculating factorial):

package main

import "fmt"

func factorial(i int)int {
   if(i <= 1) {
      return 1
   }
   return i * factorial(i - 1)
}
func main() { 
   var i int = 15
   fmt.Printf("Factorial of %d is %d", i, factorial(i))
}

Type Conversion

This converts a variable from one data type to another data type.

Syntax:

type_name(expression)

Example:

package main

import "fmt"

func main() {
   var sum int = 17
   var count int = 5
   var mean float32
   
   mean = float32(sum)/float32(count)
   fmt.Printf("Value of mean : %f\n",mean)
}

Interfaces

Interfaces represent a set of method signatures.

Syntax:

/* define an interface */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* define a struct */
type struct_name struct {
   /* variables */
}

/* implement interface methods*/
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* method implementation */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* method implementation */
}

Example:

package main

import ("fmt" "math")

/* define an interface */
type Shape interface {
   area() float64
}

/* define a circle */
type Circle struct {
   x,y,radius float64
}

/* define a rectangle */
type Rectangle struct {
   width, height float64
}

/* define a method for circle (implementation of Shape.area())*/
func(circle Circle) area() float64 {
   return math.Pi * circle.radius * circle.radius
}

/* define a method for rectangle (implementation of Shape.area())*/
func(rect Rectangle) area() float64 {
   return rect.width * rect.height
}

/* define a method for shape */
func getArea(shape Shape) float64 {
   return shape.area()
}

func main() {
   circle := Circle{x:0,y:0,radius:5}
   rectangle := Rectangle {width:10, height:5}
   
   fmt.Printf("Circle area: %f\n",getArea(circle))
   fmt.Printf("Rectangle area: %f\n",getArea(rectangle))
}

Error Handling

Error handling implies response and recovery procedures from various error conditions.

Syntax:

type error interface {
Error() string
}

Example:

package main

import "errors"
import "fmt"
import "math"

func Sqrt(value float64)(float64, error) {
   if(value < 0){
      return 0, errors.New("Math: negative number passed to Sqrt")
   }
   return math.Sqrt(value), nil
}
func main() {
   result, err:= Sqrt(-1)

   if err != nil {
      fmt.Println(err)
   } else {
      fmt.Println(result)
   }
   
   result, err = Sqrt(9)

   if err != nil {
      fmt.Println(err)
   } else {
      fmt.Println(result)
   }
}

Embedding

Go does not support subclassing. So, it uses embedding for interface and struct.

Example:

// ReadWriter implementations must satisfy both Reader and Writer
type ReadWriter interface {
    Reader
    Writer
}

// Server exposes all the methods that Logger has
type Server struct {
    Host string
    Port int
    *log.Logger
}

// initialize the embedded type the usual way
server := &Server{"localhost", 80, log.New(...)}

// methods implemented on the embedded struct are passed through
server.Log(...) // calls server.Logger.Log(...)

// the field name of the embedded type is its type name (in this case Logger)
var logger *log.Logger = server.Logger

Goroutines

Goroutines allow the functions to run independent of each other. Goroutines are basically functions that are run concurrently. You can use the “go” statement to create goroutines.

sum() // A normal function call that executes sum synchronously and waits for completing it
go sum() // A goroutine that executes sum asynchronously and doesn't wait for completing it

The go keyword makes the function call to return immediately, while the function starts running in the background as a goroutine and the rest of the program continues its execution. The goroutine starts the main function.

Example:

// just a function (which can be later started as a goroutine)
funcdoStuff(s string) {
}

funcmain() {
// using a named function in a goroutine
go doStuff("foobar")

// using an anonymous inner function in a goroutine
gofunc (x int) {
// function body goes here
}(42)
}

Channels

Channels share data between goroutines. When you execute a concurrent activity as a goroutine, it shares resources between goroutines. Channels act as a pipe between the goroutines to guarantee a synchronous exchange.

There are two types of channels based on their behavior of data exchange: unbuffered channels and buffered channels.

Syntax:

Unbuffered := make(chanint) // Unbuffered channel of integer type
buffered := make(chanint, 10) // Buffered channel of integer type

Example:

ch := make(chanint) // create a channel of type int
ch <- 42 // Send a value to the channel ch.
v := <-ch // Receive a value from ch

// Non-buffered channels block. Read blocks when no value is available, write blocks until there is a read.

// Create a buffered channel. Writing to a buffered channels does not block if less than <buffer size> unread values have been written.
ch := make(chanint, 100)

close(ch) // closes the channel (only sender should close)

// read from channel and test if it has been closed
v, ok := <-ch

// if ok is false, channel has been closed

// Read from channel until it is closed
for i := range ch {
fmt.Println(i)
}

// select blocks on multiple channel operations, if one unblocks, the corresponding case is executed
funcdoStuff(channelOut, channelIn chanint) {
select {
case channelOut <- 42:
fmt.Println("We could write to channelOut!")
case x := <- channelIn:
fmt.Println("We could read from channelIn")
case <-time.After(time.Second * 1):
fmt.Println("timeout")
}
}

Logs

Golang has a standard library package ‘log’ for log management. It traces the details, location, and time for what's happening in the program. Logs help you find potential bugs and understand the program's functioning.

Syntax:

import (
"log"
)

Example:

package main
import (
"log"
)
funcinit(){
log.SetPrefix("LOG: ")
log.SetFlags(log.Ldate | log.Lmicroseconds | log.Llongfile)
log.Println("init started")
}
funcmain() {
// Println writes to the standard logger.
log.Println("main started")

// Fatalln is Println() followed by a call to os.Exit(1)
log.Fatalln("fatal message")

// Panicln is Println() followed by a call to panic()
log.Panicln("panic message")
}

Files and Directories

Golang offers an “os” package to manipulate with files and directories.

Creating an Empty File

package main

import (
"log"
"os"
)

funcmain() {
emptyFile, err := os.Create("empty.txt")
if err != nil {
log.Fatal(err)
}
log.Println(emptyFile)
emptyFile.Close()
}

Creating a Directory

package main

import (
"log"
"os"
)

funcmain() {
_, err := os.Stat("test")

if os.IsNotExist(err) {
errDir := os.MkdirAll("test", 0755)
if errDir != nil {
log.Fatal(err)
}
}
}

Renaming a File

package main
import (
"log"
"os"
)

funcmain() {
oldName := "test.txt"
newName := "testing.txt"
err := os.Rename(oldName, newName)
if err != nil {
log.Fatal(err)
}

Copying File to Destination

package main

import (
"io"
"log"
"os"
)

funcmain() {

sourceFile, err := os.Open("/var/www/html/src/test.txt")
if err != nil {
log.Fatal(err)
}
defer sourceFile.Close()

// Create new file
newFile, err := os.Create("/var/www/html/test.txt")
if err != nil {
log.Fatal(err)
}
defer newFile.Close()

bytesCopied, err := io.Copy(newFile, sourceFile)
if err != nil {
log.Fatal(err)
}
log.Printf("Copied %d bytes.", bytesCopied)
}

Getting Metadata of a File

package main

import (
"fmt"
"log"
"os"
)

funcmain() {
fileStat, err := os.Stat("test.txt")

if err != nil {
log.Fatal(err)
}

fmt.Println("File Name:", fileStat.Name()) // Base name of the file
fmt.Println("Size:", fileStat.Size()) // Length in bytes for regular files
fmt.Println("Permissions:", fileStat.Mode()) // File mode bits
fmt.Println("Last Modified:", fileStat.ModTime()) // Last modification time
fmt.Println("Is Directory: ", fileStat.IsDir()) // Abbreviation for Mode().IsDir()
}

Deleting a File

package main

import (
"log"
"os"
)

funcmain() {
err := os.Remove("/var/www/html/test.txt")
if err != nil {
log.Fatal(err)
}
}

Reading Characters from a File

package main

import (
"bufio"
"fmt"
"io/ioutil"
"os"
"strings"
)

funcmain() {
filename := "test.txt"

filebuffer, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
inputdata := string(filebuffer)
data := bufio.NewScanner(strings.NewReader(inputdata))
data.Split(bufio.ScanRunes)

for data.Scan() {
fmt.Print(data.Text())
}
}

Truncating the Content of a File

package main

import (
"log"
"os"
)

funcmain() {
err := os.Truncate("test.txt", 100)

if err != nil {
log.Fatal(err)
}
}

Appending Content to a File

package main

import (
"fmt"
"os"
)

funcmain() {
message := "Add this content at end"
filename := "test.txt"

f, err := os.OpenFile(filename, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660)

if err != nil {
fmt.Println(err)
os.Exit(-1)
}
defer f.Close()

fmt.Fprintf(f, "%s\n", message)
}

Compressing Several Files

package main

import (
"archive/zip"
"fmt"
"io"
"log"
"os"
)

funcappendFiles(filename string, zipw *zip.Writer) error {
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("Failed to open %s: %s", filename, err)
}
defer file.Close()

wr, err := zipw.Create(filename)
if err != nil {
msg := "Failed to create entry for %s in zip file: %s"
return fmt.Errorf(msg, filename, err)
}

if _, err := io.Copy(wr, file); err != nil {
return fmt.Errorf("Failed to write %s to zip: %s", filename, err)
}

returnnil
}

funcmain() {
flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC
file, err := os.OpenFile("test.zip", flags, 0644)
if err != nil {
log.Fatalf("Failed to open zip for writing: %s", err)
}
defer file.Close()

var files = []string{"test1.txt", "test2.txt", "test3.txt"}

zipw := zip.NewWriter(file)
defer zipw.Close()

for _, filename := range files {
if err := appendFiles(filename, zipw); err != nil {
log.Fatalf("Failed to add file %s to zip: %s", filename, err)
}
}
}

Golang Regex Cheat Sheet

It is a tool that is used to describe a search pattern for matching the text. Regex is nothing but a sequence of some characters that defines a search pattern.

Extracting Text Between Square Brackets

package main

import (
"fmt"
"regexp"
"strings"
)

funcmain() {
str1 := "this is a [sample] [[string]] with [SOME] special words"

re := regexp.MustCompile(`\[([^\[\]]*)\]`)
fmt.Printf("Pattern: %v\n", re.String()) // print pattern
fmt.Println("Matched:", re.MatchString(str1)) // true

fmt.Println("\nText between square brackets:")
submatchall := re.FindAllString(str1, -1)
for _, element := range submatchall {
element = strings.Trim(element, "[")
element = strings.Trim(element, "]")
fmt.Println(element)
}
}

Find DNS Records

DNS records are mapping files that associate with DNS server whichever IP addresses each domain is associated with, and they handle requests sent to each domain. Golang provides the “net” package offering various methods to get information of DNS records.

net.LookupIP()

Returns a slice of net.IP objects that contains host's IPv4 and IPv6 addresses.

package main

import (
"fmt"
"net"
)

funcmain() {
iprecords, _ := net.LookupIP("facebook.com")
for _, ip := range iprecords {
fmt.Println(ip)
}}

Canonical Name

CNAMEs are essentially domain and subdomain text aliases to bind traffic.

package main

import (
"fmt"
"net"
)

funcmain() {
cname, _ := net.LookupCNAME("m.facebook.com")
fmt.Println(cname)
}

PTR

These records provide the reverse binding from addresses to names.

package main

import (
"fmt"
"net"
)

funcmain() {
ptr, _ := net.LookupAddr("6.8.8.8")
for _, ptrvalue := range ptr {
fmt.Println(ptrvalue)
}
}

Name Server

The NS records describe the authorized name servers for the zone.

package main

import (
"fmt"
"net"
)

funcmain() {
nameserver, _ := net.LookupNS("facebook.com")
for _, ns := range nameserver {
fmt.Println(ns)
}
}

MX Records

These records identify servers that can exchange emails.

package main

import (
"fmt"
"net"
)

funcmain() {
mxrecords, _ := net.LookupMX("facebook.com")
for _, mx := range mxrecords {
fmt.Println(mx.Host, mx.Pref)
}
}

Cryptography

Cryptography is the process of encrypting plain text into the ciphertext so that its meaning is hidden from hackers.

Example:

Classical Cipher

package main

import (
"fmt"
"unicode"
)

// Cipher encrypts and decrypts a string.
type Cipher interface {
Encryption(string) string
Decryption(string) string
}

// Cipher holds the key used to encrypts and decrypts messages.
type cipher []int

// cipherAlgorithm encodes a letter based on some function.
func (c cipher) cipherAlgorithm(letters string, shift func(int, int) int) string {
shiftedText := ""
for _, letter := range letters {
if !unicode.IsLetter(letter) {
continue
}
shiftDist := c[len(shiftedText)%len(c)]
s := shift(int(unicode.ToLower(letter)), shiftDist)
switch {
case s < 'a':
s += 'z' - 'a' + 1
case'z' < s:
s -= 'z' - 'a' + 1
}
shiftedText += string(s)
}
return shiftedText
}

// Encryption encrypts a message.
func (c *cipher) Encryption(plainText string) string {
return c.cipherAlgorithm(plainText, func(a, b int) int { return a + b })
}

// Decryption decrypts a message.
func (c *cipher) Decryption(cipherText string) string {
return c.cipherAlgorithm(cipherText, func(a, b int) int { return a - b })
}

// NewCaesar creates a new Caesar shift cipher.
funcNewCaesar(key int) Cipher {
return NewShift(key)
}

// NewShift creates a new Shift cipher.
funcNewShift(shift int) Cipher {
if shift < -25 || 25 < shift || shift == 0 {
returnnil
}
c := cipher([]int)
return &c
}

funcmain() {
c := NewCaesar(1)
fmt.Println("Encrypt Key(01) abcd =>", c.Encryption("abcd"))
fmt.Println("Decrypt Key(01) bcde =>", c.Decryption("bcde"))
fmt.Println()

c = NewCaesar(10)
fmt.Println("Encrypt Key(10) abcd =>", c.Encryption("abcd"))
fmt.Println("Decrypt Key(10) klmn =>", c.Decryption("klmn"))
fmt.Println()

c = NewCaesar(15)
fmt.Println("Encrypt Key(15) abcd =>", c.Encryption("abcd"))
fmt.Println("Decrypt Key(15) pqrs =>", c.Decryption("pqrs"))
}

MD5 and SHA-1

package main

import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"fmt"
)

funcmain() {
fmt.Println("\n----------------Small Message----------------\n")
message := []byte("Today web engineering has modern apps adhere to what is known as a single-page app (SPA) model.")

fmt.Printf("Md5: %x\n\n", md5.Sum(message))
fmt.Printf("Sha1: %x\n\n", sha1.Sum(message))
fmt.Printf("Sha256: %x\n\n", sha256.Sum256(message))
fmt.Printf("Sha512: %x\n\n", sha512.Sum512(message))

fmt.Println("\n\n----------------Large Message----------------\n")
message = []byte("Today web engineering has modern apps.")

fmt.Printf("Md5: %x\n\n", md5.Sum(message))
fmt.Printf("Sha1: %x\n\n", sha1.Sum(message))
fmt.Printf("Sha256: %x\n\n", sha256.Sum256(message))
fmt.Printf("Sha512: %x\n\n", sha512.Sum512(message))
}

 

Hash-based MAC

package main

import (
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"fmt"
"io"
)

var secretKey = "4234kxzjcjj3nxnxbcvsjfj"

// Generate a salt string with 16 bytes of crypto/rand data.
funcgenerateSalt() string {
randomBytes := make([]byte, 16)
_, err := rand.Read(randomBytes)
if err != nil {
return""
}
return base64.URLEncoding.EncodeToString(randomBytes)
}

funcmain() {
message := "Today web engineering has modern apps adhere to what is known as a single-page app (SPA) model."
salt := generateSalt()
fmt.Println("Message: " + message)
fmt.Println("\nSalt: " + salt)

hash := hmac.New(sha256.New, []byte(secretKey))
io.WriteString(hash, message+salt)
fmt.Printf("\nHMAC-Sha256: %x", hash.Sum(nil))

hash = hmac.New(sha512.New, []byte(secretKey))
io.WriteString(hash, message+salt)
fmt.Printf("\n\nHMAC-sha512: %x", hash.Sum(nil))
}

Advanced Encryption Standard (AES)

package main

import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
)

const (
keyFile = "aes.key"
encryptedFile = "aes.enc"
)

var IV = []byte("1234567812345678")

funcreadKey(filename string) ([]byte, error) {
key, err := ioutil.ReadFile(filename)
if err != nil {
return key, err
}
block, _ := pem.Decode(key)
return block.Bytes, nil
}

funccreateKey() []byte {
genkey := make([]byte, 16)
_, err := rand.Read(genkey)
if err != nil {
log.Fatalf("Failed to read new random key: %s", err)
}
return genkey
}

funcsaveKey(filename string, key []byte) {
block := &pem.Block{
Type: "AES KEY",
Bytes: key,
}
err := ioutil.WriteFile(filename, pem.EncodeToMemory(block), 0644)
if err != nil {
log.Fatalf("Failed in saving key to %s: %s", filename, err)
}
}

funcaesKey() []byte {
file := fmt.Sprintf(keyFile)
key, err := readKey(file)
if err != nil {
log.Println("Creating a new AES key")
key = createKey()
saveKey(file, key)
}
return key
}

funccreateCipher() cipher.Block {
c, err := aes.NewCipher(aesKey())
if err != nil {
log.Fatalf("Failed to create the AES cipher: %s", err)
}
return c
}

funcencryption(plainText string) {
bytes := []byte(plainText)
blockCipher := createCipher()
stream := cipher.NewCTR(blockCipher, IV)
stream.XORKeyStream(bytes, bytes)
err := ioutil.WriteFile(fmt.Sprintf(encryptedFile), bytes, 0644)
if err != nil {
log.Fatalf("Writing encryption file: %s", err)
} else {
fmt.Printf("Message encrypted in file: %s\n\n", encryptedFile)
}
}

funcdecryption() []byte {
bytes, err := ioutil.ReadFile(fmt.Sprintf(encryptedFile))
if err != nil {
log.Fatalf("Reading encrypted file: %s", err)
}
blockCipher := createCipher()
stream := cipher.NewCTR(blockCipher, IV)
stream.XORKeyStream(bytes, bytes)
return bytes
}

funcmain() {

var plainText = "AES is now being used worldwide for encrypting digital information, including financial, and government data."
encryption(plainText)

fmt.Printf("Decrypted Message: %s", decryption())
}

Conclusion

This Golang cheat sheet can help you find every basic syntax with simple examples to practice at your leisure. If you are a newbie to Golang, feel free to use this reference to tackle projects and practice tasks.

Interested in learning more about Golang? Check out our top Golang tutorials.

People are also reading:

By Sameeksha Medewar

Sameeksha is a freelance content writer for more than half and a year. She has a hunger to explore and learn new things. She possesses a bachelor's degree in Computer Science.

View all post by the author

Subscribe to our Newsletter for Articles, News, & Jobs.

I accept the Terms and Conditions.
Thanks for subscribing! Look out for our welcome email to verify your email and get our free newsletters.

Disclosure: Hackr.io is supported by its audience. When you purchase through links on our site, we may earn an affiliate commission.

In this article

Learn More

Please login to leave comments