IPv4アドレスのマスクの変換
1つ目のIPアドレスからビットを数える関数は面白半分で作ったものです。
再帰関数を使う時点でもったいない気が・・・・w
Cなら5行のbitカウントコードにするとCPUのbitカウントより早いらしいです。
namespace Doukakuorg open System open System.Text.RegularExpressions (* IPv4アドレスのマスクの変換 http://ja.doukaku.org/253/flatten/ *) type C253 public () = member this.MaskToBitOld ip = if Regex.IsMatch(ip, @"^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$") then let masks = Map.ofList [ 1, 0x55555555L; 2, 0x33333333L; 4, 0x0f0f0f0fL; 8, 0x00ff00ffL; 16, 0x0000ffffL; ] let rec bitcount mask bits = if 16 < mask then bits else bitcount (mask <<< 1) ((bits &&& masks.[mask]) + (bits >>> mask &&& masks.[mask])) let bc = bitcount 1 ip.Split('.') |> Array.map (fun a -> bc (Convert.ToInt64(a))) |> Array.sum else 0L member this.MaskToBit ip = if Regex.IsMatch(ip, @"^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$") then ip.Split('.') |> Array.map (fun a -> Convert.ToInt32(a)) |> Array.map (fun a -> Convert.ToString(a, 2)) |> Array.fold (fun s n -> s + n) "" |> (fun a -> a.Replace("0", "").Length) else 0 member this.BitToMask bit = if 1 <= bit && bit <= 32 then (new String('1', bit)).PadRight(32, '0') |> (fun a -> [for i in 0..8..(a.Length-1) do yield a.[i .. (i+7)]]) |> List.map (fun a -> Convert.ToInt32(a, 2)) |> List.fold (fun s n -> String.Format("{0}.{1}", s, n)) "" |> (fun a -> a.[1..]) else "0.0.0.0"