Friday, June 28, 2019

Generators and Iterators in JavaScript

This post concludes the series Symbols, Iterables, Iterators and Generators in JavaScript. It would be a whirlwind tour of generator functions in JavaScript and how they can be put to use when defining Iterators.

It is a direct follow up of Typing Iterables and Iterators with TypeScript and it would take the Iterator defined in the post, and improve it by making use of generator functions.

Basically, it will show how we can go from a verbose implementation that does not make use of generator functions:

class MakeRange {
    private _first: number;
    private _last: number
    constructor(first, last) {
     this._first = first;
     this._last = last;
   }
 
    [Symbol.iterator]() {
        return {
            next: () => {
                  if (this._first < this._last) {
                      return {value: this._first++, done: false}
                  } else {
                      return {value: undefined, done: true}
                 }
           }
       }
   }
 }

Into a more terse and clearer implementation that makes use of generator functions:

class MakeRange {
    private _first: number
    private _last: number

    constructor(first, last) {
     this._first = first;
     this._last = last;
    }

    *[Symbol.iterator]() {
        while (this._first < this._last) {
            yield this._first++
       }
   }
}

This post contains the following sections:

Meaning, we are going to first look at what generator functions are, then we see the various syntaxes for creating them, and finally we bring them to use in simplifying how we define iterables and iterators.

Let's get started.

Sunday, June 23, 2019

Typing Iterables and Iterators with TypeScript

In this post, we are going to do a quick exploration of how TypeScript allows for compile time guarantees when working with the iteration protocol in JavaScript.

It is part of a series about Symbols, Iterables, Iterators and Generators in JavaScript, and a direct follow up of a previous post: Iteration Protocol And Configuring The TypeScript Compiler which was about the necessary compiler configurations needed to be able to work with iterables and iterators from TypeScript.

This post will then take things from there, and show how to add types to Iterables and Iterators in other to get compile time checking working.

Saturday, June 22, 2019

Iteration Protocol And Configuring The TypeScript Compiler

This post is part of the series of post on Symbols, Iterables, Iterators and Generators. It is part of various blog posts, where I penned down some of the things I learnt about TypeScript and JavaScript, while working on ip-num: A TypeScript library for working with ASN, IPv4, and IPv6 numbers.

This post would be about how to configure the TypeScript compiler in other to be able to work with the iteration protocol.

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. I have heard it described in some quarters as "JavaScript that scales".

The core feature of TypeScript that allows it to be described as such is the static guarantees and compile time safety it introduces, which allows invariants and structure about code base to be validated and checked for correctness at compile time.

In previous posts in this series, I have looked at Symbols In JavaScript and Iterables and Iterators in JavaScript. One of the things that stands out in these posts, is the requirement to have objects that have certain structure or adhere to stipulated protocols in other to be considered as Iterables or Iterators. Formally, these sets of requirement are known as the Iteration protocol

For example, for something to be considered an Iterable, it needs to adhere to the stipulated requirement that such a thing must have a Symbol.iterator method that returns an Iterator.

For something to be considered an Iterator, it needs to adhere to the requirement of having at least a next method.

And for the value returned from calling the next method on an iterator to be considered valid, it needs to be of a certain shape; that is the value must have a done property and a value property.

So it is obvious that for things to work out fine when working with the iteration protocal, a lot of requirements and structure needs to be satisfied. This is where TypeScript can help.

TypeScript allows us to code while making sure the checks and guarantees required by the iteration protocal are present and can be confirmed at compile time.

To do this, TypeScript provides a couple of interfaces that capture the structures and protocols of iterables and iterators. These interface can then be implemented at development time ensuring the requirements are adhered to.

But in other to be able to make use of these interfaces and compile time guarantees, we need to be able to configure the Typescript compiler appropriately. This post will show how to go about such configuration and it will contain the following sections:

Tuesday, June 18, 2019

Iterables and Iterators in JavaScript

This post is the second in a series of posts on Symbols, Iterables, Iterators and Generators. The previous post in the series was about Symbols in JavaScript. This post on the other hand, will be focusing on explaining what Iterables and Iterators are in JavaScript.

It contains the following sections:

Saturday, June 15, 2019

Symbols In JavaScript

This post is part of the series on Symbols, Iterables, Iterators and Generators. It focuses on Symbols in JavaScript.

My first encounter with Symbol in JavaScript was when I wanted to turn some classes in the ip-num library to iterables in other for them to be used in the "for of" syntax JavaScript provides.

The code involving Symbol that I ended up writing looked somewhat like this:

 [Symbol.iterator](): IterableIterator<IPv4> {
      return this;
  }

You can see one of such places where this exist in the ip-num codebase here

Back then, this piece of code totally threw me off, as I have never encountered something like this previously in JavaScript, and I had to take some time out to dig into Symbol in order to understand what was going on.

This post is a jot down of some of the key things I got to learn about Symbol. It also marks the beginning of a series of posts on Iterables and Iterators in JavaScript.

This post on Symbol will contain the following:

Friday, June 14, 2019

Symbols, Iterables, Iterators and Generators

This post introduces a series of posts that would be about Symbols, Iterables, Iterators and Generators in JavaScript and TypeScript.

It would capture some of the things I learnt about these topics while working on ip-num: a TypeScript library for working with ASN, IPv4, and IPv6 numbers.

The posts in this series include:



Sunday, June 02, 2019

How to Quickly Calculate Exponents With Base 2

This post is part of the series of posts on Tips to Quickly Perform Binary and CIDR Operations. It is borne out of my experience working on ip-num, a typescript library for working with ASN, IPv4, and IPv6 numbers.

This post is about how to quickly calculate exponents with base 2.

Unfortunately I am yet to find a magical tip to use for this task that does not involve having to memorise the result of some calculations, so the core of being able to quickly perform exponents of base 2, involves some memorisation.

Below are the calculations I have come to memorise:

21 = 2
22 = 4
23 = 8
24 = 16
25 = 32
26 = 64
27 = 128
28 = 256
29 = 512
210 = 1024
216 = 65536

The only tip to know is that with each increment of the exponent, the value of the calculation doubles. For example 26 is 64, increasing the exponent by 1, ie 27 leads to 128 which is a doubling of 64.

With this, I can then easily deduce the value of 217 as the double of 65536 which is 131072.



Previous post: How To Tell If Two IP Ranges Are Adjacent

Saturday, June 01, 2019

How To Tell If Two IP Ranges Are Adjacent

This post is about how to tell if two IP ranges are adjacent. It is part of series of posts on Tips to Quickly Perform Binary and CIDR Operations.

How to tell if two IP ranges are adjacent


Task:
You have two CIDR notations representing two IP ranges, and you want to tell if they are adjacent, or not.

Steps to answer:
  • The prefix value must be the same. CIDR notations with different prefix can never be adjacent
  • Used the steps outlined in How to quickly tell the first and last IP in a CIDR range, to figure out the first and last ip numbers in the two ranges
  • Check if adding 1 to the last IP address of one will lead to the starting IP address of the other. If so, then the two ranges are adjacent

Example:
Determine if 10.0.4.0/24 and 10.0.5.0/24 are adjacent




Previous post: How To Calculate How Many Smaller IP Ranges Can Be Gotten From a Bigger IP Range
Next post: How to quickly calculate exponents of base 2

How To Calculate How Many Smaller IP Ranges Can Be Gotten From a Bigger IP Range

This post is about how to calculate how many smaller IP range are there in a bigger IP range. It is part of series of posts on Tips to Quickly Perform Binary and CIDR Operations.

How many smaller IP ranges can be gotten from a bigger IP range


Task:
You have a big IP range, and you want to break it into smaller IP range, and you want to know how many of those smaller IP range you will end up with. For example, having a /22, how many /25 are in a /22

Steps to answer:
  • Subtract the ranges.
  • Calculate 2 raised to the power of the value above.
  • The number in the previous step will be the amount of the smaller range in the big range

Example:
How much /25 are in /22?
  • 25 - 22 = 3
  • 2 raised to power 3 = 8
  • There are 8 /25 in /22


Previous post: How To Quickly Tell The First And Last IP In a CIDR Range
Next post: How to tell if two IP ranges are adjacent

How To Quickly Tell The First And Last IP In a CIDR Range

This post is part of the series of posts on Tips to Quickly Perform Binary and CIDR Operations. It is borne out of my experience working on ip-num, a typescript library for working with ASN, IPv4, and IPv6 numbers.

In this post I would show the steps I have come to use to be able to determine the start IP address depicted by a CIDR notation.

How to quickly tell the first and last ip in a CIDR range

Task: How to tell the first and last IP number in a CIDR range. Ideally the format of a CIDR range dictates that the portion of the notation that depicts the IP number should be the first number in the range, but often times, you cannot be sure that this is being adhered to when you encounter CIDR notations in the wild, so it is useful to be able to look at a CIDR notation, and tell which are the first and last IP addresses and whether the IP portion of the notation is indeed the first IP in the range.

Step to answer: Specialised to IPv4
  • Have /8, /16 and /24 as prefix bit boundaries 
  • If the prefix is any of the prefix boundary, then the starting octet will be zero and will always be in the 2nd, 3rd and 4th octet for /8, /16, /24 respectively. If the prefix under consideration is not the bit boundary, then continue with the following steps
  • Pick the bit boundary prefix which is least smaller than the prefix of the CIDR notation you are reading. So: 
    • if you have /26, pick /24
    • If you have /23, pick /16
    • If you have /19, pick /16
    • If you have /12, pick /8
    • If you have a prefix less than 8, pick /8 then follow the steps for prefix less than /8 below
  • Subtract the prefix in your CIDR notation, from the bit boundary prefix you picked above. So If you have a 10.3.4.5/19 do 19 - 16 = 3
  • Subtract the number above from 8. In this case that would be 8 - 3 = 5 
  • Find 2 raised to the power of the subtraction. For above that will be 25 = 32
  • This means the starting octet of the first IP number must be a multiple of the value calculated in previous step. For example, in previous step, the calculated value is 32, hence the starting octet must be a multiple of 32 - 32, 64, 96 etc
  • Pick which of the four octets would contain the starting octet based on the bit boundary prefix picked
  • If you pick /24, the 3rd octet will be fixed, starting will be on the 4th octet: fixed.fixed.fixed.start
  • If you pick /16, the 2nd octet will be fixed, starting will be on the 3rd octet:
    fixed.fixed.start.x
  • If you pick /8 the 1st octet will be fixed, starting will be on the 2nd octet:
    fixed.start.x.x

How To Tell Which CIDR Notation is Bigger

This post is about how to quickly tell which range, represented by CIDR notation is bigger: that is contains a higher number of IP addresses. It is part of series of posts on Tips to Quickly Perform Binary and CIDR Operations.

How to tell which CIDR notation is bigger

Task:
Given CIDR notations, be able to tell which is bigger: That is which contains more IP addresses.

Step to answer:
The CIDR notation with the biggest IP prefix, contains the lesser IP address.

This can be deduced in the steps outlined in the post: How To Tell The Count of IP Numbers In a CIDR Notation: the larger the prefix, the less the amount that would be left after it is subtracted from 32 or 128 if IPv6.

Example:
Out of the following CIDR prefix: /17, /25, /30 which is the largest and the smallest?
/17 - Largest
/30 - Smallest

I admit, it needs some getting used to, to be able to infer that the smaller number actually depicts a larger range.

Previous post: How To Tell The Count of IP Numbers In a CIDR Notation
Next post: How to quickly tell the first and last ip in a CIDR range

How To Tell The Count of IP Numbers In a CIDR Notation

This post about how to get the count of IP numbers a CIDR notation depicts, is in the series of posts on Tips to Quickly Perform Binary and CIDR Operations. It is borne out of my experience working on ip-num, a typescript library for working with ASN, IPv4, and IPv6 numbers.

How to tell the count of IP number in a CIDR notation

Task: 
You have a CIDR notation and you want to quickly calculate how many ip numbers present in the range represented by the CIDR notation.

Step to answer:
  • Subtract the CIDR prefix from 32. If it is an IPv6 address, subtract from 128
  • Raise 2 to the power of the result of the above subtraction
Example:
How many IP addresses are in a /17, /25, /30 assuming IPv4?
/17 = 2 (32-17) = 2 15 = 32768 IP addresses
/25 = 2 (32-25) = 2 7 = 128 IP addresses
/30 = 2 (32-30) = 2 2 = 4 IP addresses

Previous post: How to tell the size of IP number in a CIDR notation
Next post: How to tell which CIDR notation is bigger

Tips to Quickly Perform Binary and CIDR Operations

I maintain ip-num, a typescript library for working with ASN, IPv4, and IPv6 numbers. The library provides representations of these internet protocol numbers with the ability to perform various IP related operations like parsing, validating etc. on them

One of the side effects of working on such a library is that I get to become conversant with some bit (yup, intended) of Networking concepts: binary numbers and how that feed into how IP numbering works.

For example, how to read CIDR notations and tell how many IP number is in a range, or given a CIDR notation, how to tell if it is valid or not.

This post is just a quick pen down of some of these operations that has to do with IP numbers and ranges that I have encountered and how I have learnt to perform them quickly in my head, or at-least, with the help of some minimal jotting on a piece of paper.

This post was initially meant as a single post, but it quickly grew too long, so I am only including the first tip in this post and split the rest into various mini posts. Find the links below:

How to quickly convert binary to decimal

At around the time I started ip-num, I stumbled on an algorithm that can be used to quickly convert binary number to decimal mental. The steps was stated on this link, which unfortunately is no longer up, but the content can still be seen via the wayback machine here

It is a simple step, and instead of recreating it, I copy it as it is stated:

  • Start at the first ‘1’ on the left, and start with the mental number one
  • Move one digit right. If that digit is a zero, multiply your mental number by two. If it is a one, multiply your mental number by two and add one.
  • Repeat step 2 for every digit of the binary number

Applying these steps to convert the binary number 1011010:

  • 1011010 – We start at the first one. Our mental total: 1
  • 1011010 – Next digit is a zero; we double our mental number: 1 x 2 = 2.
  • 1011010 – Next digit is a one; we double our mental number and add one: 2 x 2 + 1 = 5
  • 1011010 – Another one; double and add one: 5 x 2 + 1 = 11
  • 1011010 – Zero; double: 11 x 2 = 22
  • 1011010 – One; double and add one: 22 x 2 + 1 = 45
  • 1011010 – And finally a zero; double: 45 x 2 = 90

Nifty right?



Next post: How to tell the size of IP number in a CIDR notation