Contents of this directory is archived and no longer updated.

Недавно в мессенджер упал интересный вопрос:

в Active Directory у пользователя есть атрибут msRADIUSFramedIPAddress в котором храниться статический IP адрес, который назначается на вкладке Dual In в свойствах пользователя. Если смотреть через LDAP то значение мало похоже на введённый IP адрес. Хотелось бы на выходе получить работающий скрипт пишущий в файл соответсвие пользователь - IP адрес. Как я понял проблему, идёт двойная конвертация.

Действительно, если смотреть на это свойство через провайдер ADSI (не путать с adsiedit.msc), мы увидим число мало похожее на IP адрес. Например, 168846386. Для приведения данного числа в формат IP адреса нужно преобразовать его в двоичный формат, а после — разбить на октеты по 8 бит и каждый октет преобразовать обратно в десятичную форму. В .NET есть целый класс конверторов System.Convert, который позволяет конвертировать между собой множество форматов. Мы воспользуемся вот таким методом: Convert::ToString Method (Int32, Int32), в котором первый аргумент отвечает за исходное число, а второй — выходной формат. Поскольку нам нужно получить двоичное представение, указываем формат 2:

[↓] [vPodans] [convert]::ToString(168846386,2)
1010000100000110010000110010

Строка содержит неполные 32 бита. Чтобы их дополнить мы должны добавить слева недостающие нули:

[↓] [vPodans] $bin = [convert]::ToString(168846386,2)
[↓] [vPodans] $bin
1010000100000110010000110010
[↓] [vPodans] $bin.length
28
[↓] [vPodans] $fullBin = "0" * (32 - $bin.length) + $bin
[↓] [vPodans] $fullbin
00001010000100000110010000110010

Мы знаем, что 4 октета это 32 бита, следовательно вычитаем из 32 длину актуальной строки и получаем количество добавочных нулей. И эти нули добавляем в начало строки. Теперь эту строку надо разбить на 4 октета по 8 бит или по 1 байту:

[↓] [vPodans] 0,8,16,24 | %{$fullbin.substring($_,8)}
00001010
00010000
01100100
00110010

Я воспользовался методом String::Substring Method (Int32, Int32). Первый аргумент указывает стартовый символ, откуда начинать вырезать, а второй аргумент указывает количество символов, которые нужно вырезать. Вот и получили 4 байта. Преобразовать обратно в десятичный формат их так же просто, но с использованием Convert::ToInt32 Method (String, Int32):

[↓] [vPodans] 0,8,16,24 | %{[convert]::ToInt32($fullbin.Substring($_,8),2)}
10
16
100
50

Теперь это осталось собрать в строку и расставить точки между октетами. Для этого мы вопспользуемся статическим методом Join() класса System.String:

[↓] [vPodans] [string]::Join(".",$(0,8,16,24 | %{[convert]::ToInt32($fullbin.substring($_,8),2)}))
10.16.100.50

вот мы и получили наш заветный IP-адрес. И вот весь код:

$bin = [Convert]::ToString(168846386,2)
$fullBin = "0" * (32 - $bin.Length) + $bin
[string]::Join(".", $(0,8,16,24 | %{[Convert]::ToInt32($fullBin.Substring($_,8),2)}))

Надеюсь, поможет ещё кому-нибудь :-)


Share this article:

Comments:

Vadims Podāns

Мне в почту Serge Nikalaychuk подсказал ещё один метод: [System.Net.IPAddress]::Parse(168846386).IPAddressToString

Comments are closed.