Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Расчёт маски подсети (обычная + CIDR)

Ответить
Настройки темы
CMD/BAT - Расчёт маски подсети (обычная + CIDR)

Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить PM | Цитировать


Доработал один из своих старых скриптов, добавив в него поддержу 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

 


Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Расчёт маски подсети (обычная + CIDR)

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Расчёт заработной платы менеджера 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




 
Переход