Sunday, April 14, 2019
Tuesday, March 5, 2019
Hashing and Encryption
Consider a database table which stores user id and password in plain text. If a hacker gets access to the table, he can easily login to the application that uses the user id and passwords and steal user information. Hence, there is a need to store passwords in a secure way. How do we do it? There are two ways - Hashing and Encryption.
Hashing
Hashing is the process of converting a text into a string or number that cannot be reversed back to the original form. It is a one-way conversion to a hash. Best use case would be storing a password in a database. Passwords can be hashed and stored in tables. So, even in case of hacker attack, it would be impossible to retrieve what the user entered.
Hashing algorithms
MDA5 - Produces a 16-byte hash value, expressed as a 32 digit hexadecimal number. Recently, a vulnerability was found when using MD5.
SHA - 0 - Very rarely used, as it contained an error
SHA - 1 - Rectified the error of SHA-0. It produces a 20-byte hash value. Most commonly used.
SHA - 2 - Produces 32-byte hash value. Considered to be the strongest and comprises of 6 hashing algorithms.
Salt - A random number added to the text to be hashed and then hashed. The resulting hash is a product of both the text and the random number which makes it harder to retrieve.
Rainbow table - An attacker can run a hashing algorithm over a list of commonly used passwords and match it against the values in the database. This list is called a rainbow table. Salts are added to the text to make it more difficult for a hacker to come up with a rainbow table.
Encryption
Encryption is a two way conversion wherein, a text can be converted or encrypted using a key into a non-readable format to transfer it over a network, which then can be decrypted back to its original form at the receiver’s end. There are two types of encryption - symmetric encryption and public key encryption.
Consider a use case - Suppose Rita wants to send a secret message to Anita, she can send it as plain text over the network, which an eavesdropper can get. Encryption comes into use in such cases.
Rita and Anita can share a common encryption key. So, Rita can encrypt her message using the common encryption key and send the encrypted message over network. Anita on the other end, can decrypt the message using the common encryption key. This form of encryption is known as symmetric encryption where the same encryption key is used to encrypt and decrypt messages or text.
Public key encryption or Asymmetric encryption - In public key encryption, each user has two keys. A public key(known to everyone) and a private key(known only to the owner).
Public key is used to encrypt and private key is used to decrypt.
In Rita and Anita’s use case, Rita will use Anita’s public key to encrypt the message. And Anita will use her private key to decrypt the message.
LDAP technology can be used to store a registry of public keys.
PGP - Pretty Good Privacy is a well known public key system for transmitting information.
Encryption Algorithms
AES - Used widely symmetric key encryption
PGP - Popular public key encryption algorithm.
When to use what?
If a text needs to be sent securely with the message to be available in its raw form at receiver end, then encryption is the best bet.
In cases where the raw form is not required, hashing can be used.
Symmetric encryption is simpler to use and has an improved performance. However, both parties need to be aware of the encryption key to use. Public key encryption can be used to send across symmetric key for the first time and later on symmetric encryption can be used thereafter- eliminating the challenge of sharing the key securely.
Thursday, January 11, 2018
Web Service client code
I have been watching tutorials on Web services, especially, Restful web service ones.
The following snippet of code shows how to consume a restful webservice.
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.client.Response;
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
// The main URL of the Restful webservice
WebTarget target = client.target("http://localhost:8080/advancedjaxrs/webapi/");
// messages could be replaced with comments or likes or whatever context needs to be fetched.
WebTarget path = target.path("messages");
// messageId is the specific id to be passed for fetch of specific message
WebTarget path2 = path.path("{messageId}");
//First way of getting a response.
Response reponse = path2.resolveTemplate("messageId", "1").request().get();
//Read response
Message m1 = reponse.readEntity(Message.class);
System.out.println(m1.getMessage());
// Second way of reading a response - Directly, we use Message object to get a Message object.
Message message1 = path2
.resolveTemplate("messageId", "1")
.request()
.get(Message.class);
// TO check errors in response, if we map it to a String object, we can get the response as String.
String message2 = path2
.resolveTemplate("messageId", "2")
.request()
.get(String.class);
System.out.println(message1.getMessage());
System.out.println(message2);
}
The following snippet of code shows how to consume a restful webservice.
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.client.Response;
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
// The main URL of the Restful webservice
WebTarget target = client.target("http://localhost:8080/advancedjaxrs/webapi/");
// messages could be replaced with comments or likes or whatever context needs to be fetched.
WebTarget path = target.path("messages");
// messageId is the specific id to be passed for fetch of specific message
WebTarget path2 = path.path("{messageId}");
//First way of getting a response.
Response reponse = path2.resolveTemplate("messageId", "1").request().get();
//Read response
Message m1 = reponse.readEntity(Message.class);
System.out.println(m1.getMessage());
// Second way of reading a response - Directly, we use Message object to get a Message object.
Message message1 = path2
.resolveTemplate("messageId", "1")
.request()
.get(Message.class);
// TO check errors in response, if we map it to a String object, we can get the response as String.
String message2 = path2
.resolveTemplate("messageId", "2")
.request()
.get(String.class);
System.out.println(message1.getMessage());
System.out.println(message2);
}
Thursday, November 2, 2017
Day 5 - Generics
Generics - Basically, Generics allows you to generalize what you put in the data structures. For example, let's take an example of a LinkedList of Integers. We define it as:
LinkedList intList = new LinkedList<>();
Similarly, we define list of Strings as:
LinkedList stringList = new LinkedList<>();
Suppose we create a method printArray() to print the above lists. We do it by creating two methods:
printArray(LinkedList
printArray(LinkedList
Generics allows to have a Generic datastructure in the following way:
private void printArray(E[] argArray){
for(E element: argArray){
System.out.println(element);
}
}
E can be a Integer, String or any other Object. The limitation here is the element of type is E is limited to operations pertaining to Object such as wait(), notify(), hashCode() etc.
If we need to define a Type in a class to be used in the class, they can be defined as:
class Printer { // Define the Type along with class name.
D arr;
public void printArray(T[] array) {
for(T element: array){
System.out.println(element);
}
}
}
LinkedList
Similarly, we define list of Strings as:
LinkedList
Suppose we create a method printArray() to print the above lists. We do it by creating two methods:
printArray(LinkedList
printArray(LinkedList
Generics allows to have a Generic datastructure in the following way:
private
for(E element: argArray){
System.out.println(element);
}
}
E can be a Integer, String or any other Object. The limitation here is the element of type is E is limited to operations pertaining to Object such as wait(), notify(), hashCode() etc.
If we need to define a Type in a class to be used in the class, they can be defined as:
class Printer
D arr;
public
for(T element: array){
System.out.println(element);
}
}
}
Sunday, October 29, 2017
Day 4 - Bubble Sort
Bubble Sort - This is a simple sorting algorithm where elements of an array are swapped until sorting is achieved. It is a very inefficient algorithm. The basic theory behind bubble sorting is take an array of size n; iterate over the list; for each element at index i, if it greater than the element at next index (i+1), swap them. This causes the greater elements to go to the back of the array.
Implementation:
public class BubbleSort {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n];
for(int a_i=0; a_i < n; a_i++){
a[a_i] = in.nextInt();
}
int swap = 0;
for(int i=0;i
for(int j=i+1;j
if(a[i]>a[j]){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
swap ++;
}
}
}
System.out.println("Array is sorted in "+swap+" swaps.");
System.out.println("First element: "+a[0]);
System.out.println("Last element: "+a[n-1]);
}
}
Implementation:
public class BubbleSort {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n];
for(int a_i=0; a_i < n; a_i++){
a[a_i] = in.nextInt();
}
int swap = 0;
for(int i=0;i
for(int j=i+1;j
if(a[i]>a[j]){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
swap ++;
}
}
}
System.out.println("Array is sorted in "+swap+" swaps.");
System.out.println("First element: "+a[0]);
System.out.println("Last element: "+a[n-1]);
}
}
Input:
3
3 2 1
Output:
Array is sorted in 0 swaps.
First element: 1
Last element: 3
Friday, October 27, 2017
Day 2 - Queues & Stacks
Queues
Queues are data structures that follow the pattern of FIFO(first-in, first-out). It is similar to people standing in a queue. The first person gets serviced first.
The third person gets serviced after the first and second persons.
Similarly, in a queue, to get to the third element, first and second element need to be retrieved.
A simple implementation of a queue.
import java.util.LinkedList;
// Queue operate in FIFO. So, the first element added, gets out first.So, if we have to get the third element,
//we need to remove the first two elements to get to the third element
//Operations of a queue
// Check if queue is empty
// Get size of queue
// Enqueue - Add element to a queue
// Dequeue - Remove element from a queue. Usually the first element gets removed.
// Peek - Get the first element from a queue
public class Queue {
private LinkedList queue;
public Queue(){
queue = new LinkedList();
}
public boolean isEmpty(){
return queue.isEmpty();
}
public int size(){
return queue.size();
}
public void enqueue(int data){
queue.add(data);
}
public int dequeue(){
return (int)queue.remove(0);// When you remove the first element from a linked list, the second element becomes the head.
}
public int peek(){
return (int)queue.get(0);
}
public static void main(String[] args) {
Queue queue = new Queue();
queue.enqueue(5);
queue.enqueue(6);
queue.enqueue(7);
System.out.println("Size of queue:"+queue.size());
System.out.println("First element:"+queue.dequeue());
System.out.println("First element:"+queue.peek());
System.out.println("Second element:"+queue.dequeue());
System.out.println("Third element:"+queue.dequeue());
System.out.println("Is the queue emepty:"+queue.isEmpty());
System.out.println("Size of queue after dequeuing:"+queue.size());
}
}
Queues are data structures that follow the pattern of FIFO(first-in, first-out). It is similar to people standing in a queue. The first person gets serviced first.
The third person gets serviced after the first and second persons.
Similarly, in a queue, to get to the third element, first and second element need to be retrieved.
A simple implementation of a queue.
import java.util.LinkedList;
// Queue operate in FIFO. So, the first element added, gets out first.So, if we have to get the third element,
//we need to remove the first two elements to get to the third element
//Operations of a queue
// Check if queue is empty
// Get size of queue
// Enqueue - Add element to a queue
// Dequeue - Remove element from a queue. Usually the first element gets removed.
// Peek - Get the first element from a queue
public class Queue {
private LinkedList queue;
public Queue(){
queue = new LinkedList();
}
public boolean isEmpty(){
return queue.isEmpty();
}
public int size(){
return queue.size();
}
public void enqueue(int data){
queue.add(data);
}
public int dequeue(){
return (int)queue.remove(0);// When you remove the first element from a linked list, the second element becomes the head.
}
public int peek(){
return (int)queue.get(0);
}
public static void main(String[] args) {
Queue queue = new Queue();
queue.enqueue(5);
queue.enqueue(6);
queue.enqueue(7);
System.out.println("Size of queue:"+queue.size());
System.out.println("First element:"+queue.dequeue());
System.out.println("First element:"+queue.peek());
System.out.println("Second element:"+queue.dequeue());
System.out.println("Third element:"+queue.dequeue());
System.out.println("Is the queue emepty:"+queue.isEmpty());
System.out.println("Size of queue after dequeuing:"+queue.size());
}
}
Output:
Size of queue:3
First element:5
First element:6
Second element:6
Third element:7
Is the queue emepty:true
Size of queue after dequeuing:0
Java does have a Queue Interface where the above operations as well as some other useful methods are available, which can be implemented using LinkedList.
The only way to traverse a stack or a queue is to pop/dequeue - which means we remove all the elements in the queue to get to the desired element/index. So, unless we store the dequeued /popped elements in another variable, they will be lost.
Stacks
Stack is a data structure which behaves in the LIFO (last-in, first-out) fashion.
Taking the example of people standing a queue, the last person who came in, gets serviced first. And the first person gets serviced last. (Sounds weird, isn't it?)
Java already has a built in feature class called stack.
Stack has the following features:
Push: Push/Inset an element.
Pop: Pop/Remove element
Peek: Returns the first element.
Taking an example:
import java.util.Stack;
public class StackEx {
public static void main(String[] args) {
Stack strStack = new Stack();
strStack.push("Hi ");
strStack.push("There ");
System.out.println("First element/Peek:"+strStack.peek());
System.out.print(strStack.pop());
System.out.println(strStack.pop()+"!");
}
}
Output:
First element/Peek:There
There Hi !
The first element pushed into the stack was 'Hi'. But the first element popped out was 'There'.
Another point is if we do a peek() operation after all the pop operations, it will give an IndexOutOfBoundsException. . Because, just like queues, when all elements are popped, the stack becomes empty.
Comparing it with Queue.
public static void main(String[] args) {
Queue queue = new Queue();
queue.enqueue("Hi ");
queue.enqueue("There ");
System.out.print(queue.dequeue());
System.out.println(queue.dequeue()+"!");
}
Output:
Hi There !
The queue pops out in whatever way the elements are inserted into the queue.
Thursday, October 26, 2017
Day 1 - Linked lists
Linked lists: Linked list is a list data structure where each element basically holds data as well as the reference to the next element.
Each element in a Linked List has two parts - Data (can be an Intger, String, Object) and a reference to the next element. Element of a linked list is also known as a node, perhaps for these reasons.
To define an element in a linked list.
//Linked list have two things: data and reference to the next node.
// Here 'next' is a reference to the next node and 'data' is the value the node holds.
// 'data' is not limited to being an int. It could be a String, Object, float or any other datatype
public class Node {
Node next;
int data;
public Node(int newData){
data = newData;
}
public Node(Node newNode, int newData){
next = newNode;
data = newData;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
To create a linked list data structure -
import java.util.Scanner;
// Add nodes
// Remove nodes
// IsNodesavailable
// Get data related to a node
public class LinkedList {
static Node head; //First node
static int count; // count - tracks the number of nodes in the linked list
public LinkedList(){
head = null;
count = 0;
}
public LinkedList(Node newNode){
head = newNode ;
count ++;
}
// Add method - Create a new node with the data value as data
public static Node add(int data){
Node temp = new Node(data);
if(count==0){
head = temp;
}
Node current = head;
while(current.getNext()!=null){
current = current.getNext();
}
if(count>0){
current.setNext(temp);
}
count++;
return head;
}
// Get the data at node
public int get(int index){
if(index<=0){
return -1;
}
Node current = head;
for(int i=1;i
current = current.getNext();
}
return current.getData();
}
public int size(){
return count;
}
public boolean isEmpty(){
return head==null;
}
// Remove the last node from the list
public void remove(){
Node current = head;
while(current.getNext().getNext()!=null){
current = current.getNext();
}
current.setNext(null);
count--;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Node head = null;
int N = sc.nextInt();
while (N-- > 0) {
int ele = sc.nextInt();
head = add(ele);
}
display(head);
sc.close();
}
public static void display(Node head) {
Node start = head;
while (start != null) {
System.out.print(start.getData() + " ");
start = start.getNext();
}
}
}
Each element in a Linked List has two parts - Data (can be an Intger, String, Object) and a reference to the next element. Element of a linked list is also known as a node, perhaps for these reasons.
To define an element in a linked list.
//Linked list have two things: data and reference to the next node.
// Here 'next' is a reference to the next node and 'data' is the value the node holds.
// 'data' is not limited to being an int. It could be a String, Object, float or any other datatype
public class Node {
Node next;
int data;
public Node(int newData){
data = newData;
}
public Node(Node newNode, int newData){
next = newNode;
data = newData;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
To create a linked list data structure -
import java.util.Scanner;
// Add nodes
// Remove nodes
// IsNodesavailable
// Get data related to a node
public class LinkedList {
static Node head; //First node
static int count; // count - tracks the number of nodes in the linked list
public LinkedList(){
head = null;
count = 0;
}
public LinkedList(Node newNode){
head = newNode ;
count ++;
}
// Add method - Create a new node with the data value as data
public static Node add(int data){
Node temp = new Node(data);
if(count==0){
head = temp;
}
Node current = head;
while(current.getNext()!=null){
current = current.getNext();
}
if(count>0){
current.setNext(temp);
}
count++;
return head;
}
// Get the data at node
public int get(int index){
if(index<=0){
return -1;
}
Node current = head;
for(int i=1;i
current = current.getNext();
}
return current.getData();
}
public int size(){
return count;
}
public boolean isEmpty(){
return head==null;
}
// Remove the last node from the list
public void remove(){
Node current = head;
while(current.getNext().getNext()!=null){
current = current.getNext();
}
current.setNext(null);
count--;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Node head = null;
int N = sc.nextInt();
while (N-- > 0) {
int ele = sc.nextInt();
head = add(ele);
}
display(head);
sc.close();
}
public static void display(Node head) {
Node start = head;
while (start != null) {
System.out.print(start.getData() + " ");
start = start.getNext();
}
}
}
Input
4 (number of elements in list)
2
3
4
1
Output:
2 3 4 1
Linked lists over Arrays - In arrays, the elements are indexed. For example, in an array of [2,4,1,5], the element at arr[3] can be easily retrieved. However, in linked list, we need to traverse from the beginning of the linked list.
So, retrieval of an element in a linked list takes linear time - O(n)
whereas in an array takes constant time - O(1)
The advantage lies in the fact that insertions and deletions in a linked list are much quicker.
Insertion/Deletion at beginning of the linked list or prepend to the linked list - O(1) -- constant time
Insertion/Deletion at end of the linked list or append to the linked list - O(n) -- linear (as we need to traverse from the beginning till end of the linked list)
Doubly linked list have references to both the nodes/
i.e.
class Node {
Node prev;
Node next;
int data;
}
So, in a doubly linked list, the last node's 'next' reference will null and the first node's 'prev' reference will be null. All other elements in between have 'prev' and 'next' reference.
In a singly linked list, the last node's 'next' reference will be null.
A brief tutorial is presented in:
https://www.youtube.com/watch?v=njTh_OwMljA
Courtesy: Hackerrank site
Subscribe to:
Comments (Atom)
