Canonicalize CIDR: Difference between revisions

Add a Common Lisp solution
m (→‎{{header|ALGOL 68}}: Remove unused declaration)
(Add a Common Lisp solution)
Line 447:
161.214.74.21/24 => 161.214.74.0/24
184.232.176.184/18 => 184.232.128.0/18</pre>
 
=={{header|Common Lisp}}==
<lang lisp>(defun ip->bit-vector (ip)
(flet ((int->bits (int)
(loop :for i :below 8
:collect (if (logbitp i int) 1 0) :into bits
:finally (return (nreverse bits)))))
(loop :repeat 4
:with start := 0
:for pos := (position #\. ip :start start)
:collect (parse-integer (subseq ip start pos)) :into res
:while pos
:do (setf start (1+ pos))
:finally (return (apply #'concatenate 'bit-vector (mapcar #'int->bits res))))))
 
(defun bit-vector->ip (vec &optional n)
(loop :repeat 4
:for end :from 8 :by 8
:for start := (- end 8)
:for sub := (subseq vec start end)
:collect (parse-integer (map 'string #'digit-char sub) :radix 2) :into res
:finally (return (format nil "~{~D~^.~}~@[/~A~]" res n))))
 
(defun canonicalize-cidr (cidr)
(let* ((n (position #\/ cidr))
(ip (subseq cidr 0 n))
(sn (parse-integer (subseq cidr (1+ n))))
(ip* (ip->bit-vector ip))
(canonical-ip (fill ip* 0 :start sn)))
(bit-vector->ip canonical-ip)))
 
(loop :for cidr :in '("36.18.154.103/12" "62.62.197.11/29"
"67.137.119.181/4" "161.214.74.21/24"
"184.232.176.184/18")
:for ccidr := (canonicalize-cidr cidr)
:do (format t "~&~A~20,T→ ~A~%" cidr ccidr))
</lang>
{{out}}
<pre>
36.18.154.103/12 → 36.16.0.0/12
62.62.197.11/29 → 62.62.197.8/29
67.137.119.181/4 → 64.0.0.0/4
161.214.74.21/24 → 161.214.74.0/24
184.232.176.184/18 → 184.232.128.0/18</pre>
 
=={{header|Factor}}==