Skip to content

Instantly share code, notes, and snippets.

@rmbolger
Last active September 24, 2020 17:10
Show Gist options
  • Save rmbolger/37163a50e367eed677fc588864812935 to your computer and use it in GitHub Desktop.
Save rmbolger/37163a50e367eed677fc588864812935 to your computer and use it in GitHub Desktop.
Sorting classes for FQDNs and CIDR strings
# I like to add these to my PowerShell profile so I can more easily sort FQDNs and CIDR network strings.
# The FQDN sorter will sort based on the labels in reverse order. So .com's will sort near each other,
# everything within the same domain will sort near each other, etc.
#
# 'a.example.org','a.example.com','example.org','example.com' | sort {[Fqdn]$_}
class Fqdn : IComparable
{
[string]$Fqdn
hidden [string] $_namespaceOrder = $null
Fqdn(
[string]$_fqdn
){
$this.Fqdn = $_fqdn
}
[int]
CompareTo([object]$other)
{
if($other -isnot [Fqdn]){
throw [ArgumentException]::new('other')
}
return [string]::Compare(
$this.GetNamespaceOrder(),
$other.GetNamespaceOrder(),
[StringComparison]::InvariantCultureIgnoreCase
)
}
hidden [string] GetNamespaceOrder()
{
if (-not $this._namespaceOrder) {
$labels = $this.Fqdn.Split('.')
[array]::Reverse($labels)
$this._namespaceOrder = $labels -join '.'
}
return $this._namespaceOrder
}
[string]
ToString()
{
return $this.Fqdn.ToString()
}
}
# The CIDR sorter expects strings such as 10.0.11.0/24, 10.0.2.0/24, 10.0.2.0/22
# It will sort by the IP portion first and if the IPs match, then use the mask integer.
#
# '10.0.11.0/24','10.0.2.0/24','10.0.2.0/22' | sort {[Cidr]$_}
class Cidr : IComparable
{
[string]$Cidr
hidden [version] $_ip
hidden [int] $_mask
Cidr(
[string]$_Cidr
){
$this.Cidr = $_Cidr
}
[int]
CompareTo([object]$other)
{
if ($other -isnot [Cidr]) {
throw [ArgumentException]::new('other')
}
$ipCompare = $this.GetIP().CompareTo($other.GetIP())
if (0 -ne $ipCompare) {
return $ipCompare
} else {
return ($this.GetMask().CompareTo($other.GetMask()))
}
}
hidden [version] GetIP()
{
if (-not $this._ip) {
$this._ip = [version]$this.Cidr.Substring(0, $this.Cidr.IndexOf('/'))
}
return $this._ip
}
hidden [int] GetMask()
{
if (-not $this._mask) {
$this._mask = [int]$this.Cidr.Substring($this.Cidr.IndexOf('/')+1)
}
return $this._mask
}
[string]
ToString()
{
return $this.Cidr.ToString()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment