Если стоит задача именно максимально быстрого поиска, то вот тут я уже отвечал на похожий вопрос:
Как ускорить поиск элементов из статичного string[] по подстроке? и там же есть ссылка на готовый код примера реализации на шарпе. Если кратко: тупо дерево таблиц переходов, на весь диапазон IPv4 - 17 гигабайт памяти и практически мгновенный поиск. Если на списках - то поиск примерно в 1-1000 раз медленнее и значительнее меньше затраты памяти.
Примерно так:
public struct Organization
{
public UInt64 Asn;
public string Name;
}
var tree = ArrayTree<Organization>();
var org1 = new Organization() { Asn = 13238, Name = "YANDEX LLC" };
tree.Add(IPAddress.Parse("5.45.192.0").GetAddressBytes(), org1);
В данном случае немного доработать логику путем добавления в узел еще одного поля с cылкой на структуру организации и в диапазонах втором/третьем байте сначала проверять это поле, а потом уже дальше по цепочке идти. Ну или можно для простоты сгененрировать конечные узлы для каждой организации и просто сразу на втором/третьем шаге их линковать для нужного числа адресов, что позволит сократить расход памяти.
Измерил расход памяти для 400к записей: 1.6 и 3.6GB для х86 и х64 соответственно для ArrayTree. Для ListTree - 400 Мб.