|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Расчёт маски подсети (обычная + CIDR) |
|
CMD/BAT - Расчёт маски подсети (обычная + CIDR)
|
Старожил Сообщения: 415 |
Доработал один из своих старых скриптов, добавив в него поддержу CIDR-формата маски. Возможно, кому-то понадобится для решения сходной задачи, поэтому решил поделиться с сообществом.
Использование: netmask <начальный IP диапазона> <конечный IP диапазона> netmask <начальный IP диапазона> <конечный IP диапазона> cidr Примеры: netmask 195.189.120.0 195.189.123.255 = 255.255.252.0 netmask 195.189.120.0 195.189.123.255 CIDR = /22 @Echo Off :: # :: # Subnet mask from IP range v2.1 :: # Inquisitor, 2012-2013 :: # Distributed under GNU GPL v2 license :: # http://www.gnu.org/licenses/gpl-2.0.html :: # :: # USAGE: NetMask.cmd first_ip_from_range last_ip_from_range :: # or, for display in CIDR format :: # NetMask.cmd first_ip_from_range last_ip_from_range cidr :: # SetLocal EnableDelayedExpansion Set NetworkHostBoundary=false Set NetMask= :: Если вызывается не из консоли, а из другого батника, :: вызывать нужно из цикла for для корректной работы :: Пример: rem For /F %%A In ('netmask.cmd 192.168.1.0 192.168.8.255') Do Echo %%A :: Проверка на запуск с аргументами :: Если без аргументов - пример использования и выход If "%*"=="" ( For /F "tokens=1,* delims=#" %%A In ('FindStr /R /B "::.#" "%~dpnx0"') Do ( Echo.%%B ) GoTo :EOF ) :: Разбор входящих аргументов, cравнение начального и конечного :: адресов по октетам For /F "tokens=1-9 delims=. " %%A In ("%*") Do ( Call :Mask %%A %%E Call :Mask %%B %%F Call :Mask %%C %%G Call :Mask %%D %%H If /I "%%I"=="CIDR" Call :CIDR ) :: Вывод в stdout результата и выход, раскомментировать нужное :: Вывод _БЕЗ_ перевода строки <Nul Set /P Echo=!NetMask! :: Вывод _С_ переводом строки rem Echo !NetMask! GoTo :EOF :DEC2BIN :: Функция перевода числа из десятеричной системы в двоичную :: Принимает один аргумент, результат возвращается в %Result% Set Result= Set Data=%~1 :d2b_loop :: Проверяем, есть ли остаток от деления Set /A x1=Data/2 Set /A x2=x1*2 If "%x2%"=="%Data%" (Set Mod=0) Else (Set Mod=1) :: Устанавливаем в качестве входных данных результат деления Set Data=%x1% :: Пишем результат поразрядно, в обратном порядке Set Result=%Mod%%Result% :: Следующая итерация или выход после окончания If Not "%x1%"=="0" GoTo d2b_loop :: Перед выходом - дополнение ведущими нулями до двух в восьмой :: Требуется для корректного сравнения двух чисел без сдвига Call :LeadingZero %Result% GoTo :EOF :BIN2DEC :: Функция перевода числа из двоичной системы в десятеричную :: Принимает один аргумент, результат возвращается в %Result% Set Result= :: Значение -1 для начала значения счетчика с нуля Set i=-1 Set Data=%1 :b2d_loop :: Получаем текущий разряд числа Set /A i+=1 Set x1=%Data:~-1% :: Используем бинарный сдвиг для получения степени двойки Set /A x2="x1 * (1 << i)" :: Добавляем к результату Set /A Result+=%x2% :: Следующая итерация или выход после окончания If Not "%Data:~,-1%"=="" (Set Data=%Data:~,-1%&GoTo b2d_loop) GoTo :EOF :LeadingZero :: Дополнение ведушими нулями до двух в восьмой (один байт) :: Принимает один аргумент, результат возвращается в %Result% Set Result= Set Data=%~1 For /L %%A In (1,1,8) Do ( If Not "!Data!"=="" ( Set Result=!Data:~-1!!Result! Set Data=!Data:~,-1! ) Else ( Set Result=0!Result! ) ) GoTo :EOF :FastCompare :: Быстрое сравнение, если найдены различия - вызывается функция :: более детального сравнения для поиска самого различия :: Принимает два аргумента, результат возвращается в %Result% If Not !NetworkHostBoundary!==true ( If "%1"=="%2" ( Set Result=11111111 GoTo :EOF ) Else ( Call :Compare %1 %2 ) ) Else ( Set Result=00000000 ) GoTo :EOF :Compare :: Сравнение двух однобайтных чисел поразрядно, локализация начала различий :: и забивание всего после первого различия нулями :: Принимает два аргумента, результат возвращается в %Result% :: Ведущие нули у обоих чисел обязательны Set x1=%1&Set x2=%2 Set Result= For /L %%A In (1,1,8) Do ( :: Получение ведущего разряда от каждого из чисел Set n1=!x1:~,1! Set n2=!x2:~,1! :: Сравнение двух чисел и инвертирование бита Set /A Data="1 ^ (n1 ^ n2)" :: Установка флага начала различия If !Data!==0 Set NetworkHostBoundary=true :: Обнуление всех последующих после различия разрядов If !NetworkHostBoundary!==true Set Data=0 :: Поразрядная запись результата Set Result=!Result!!Data! :: Устанавливаем остаток в качестве входных данных для следующей итерации Set x1=!x1:~1! Set x2=!x2:~1! ) GoTo :EOF :Mask :: Генерация одного октета маски :: Принимает два аргумента, результат дописывается к %NetMask% Call :DEC2BIN %1&&Set From=!Result! Call :DEC2BIN %2&&Set To=!Result! Call :FastCompare !From! !To! Call :BIN2DEC !Result! If "!NetMask!"=="" (Set NetMask=!Result!) Else (Set NetMask=!NetMask!.!Result!) GoTo :EOF :CIDR :: Трансформация маски в формат CIDR Set BinMask= Set i=0 :: Разбираем маску обратно на октеты Set NetMask=!NetMask:.= ! For %%A In (!NetMask!) Do ( Call :DEC2BIN %%A :: И собираем бинарную маску Set BinMask=!BinMask!!Result! ) :: Удаляем из неё незначащие нули, а единицы разделяем пробелами Set BinMask=!BinMask:0=! Set BinMask=!BinMask:1=1 ! :: Считаем единицы For %%A In (!BinMask!) Do (Set /A i+=1) :: Устанавливаем значение Set NetMask=/!i! Exit /B |
|
Отправлено: 18:05, 26-04-2013 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Расчёт заработной платы менеджера | Tonny_Bennet | Флейм | 2 | 21-10-2011 17:01 | |
Расчёт производительности процессора | Hardman | Процесcоры | 8 | 15-05-2009 18:56 | |
вопрос по CIDR | XPurple | Сетевые технологии | 1 | 24-08-2007 13:05 | |
укороченые маски | slaine | Сетевые технологии | 4 | 09-02-2006 11:08 | |
вычисление маски подсети | aniuta | Сетевые технологии | 2 | 13-02-2004 09:57 |
|