понедельник, 24 августа 2020 г.

Калькулятор консольный на Java

Условие задачи:

Необходимо написать простой консольный калькулятор на Java.

 Для считывания ввода нужно использовать класс Scanner. 

Scanner позволяет считывать строки и числа:

Scanner scanner = new Scanner(System.in);

int operand1 = scanner.nextInt(); //считывает число

/* Метод next() класса Scanner считывает строку,

а метод charAt(0) позволяет взять первый символ в этой строке.

так мы получаем операцию, которую нужно выполнить*/

char operation = scanner.next().charAt(0);

 

Теперь у нас есть первый операнд и операция, которую необходимо выполнить. Осталось считать второй операнд, и выполнить нужное действие в зависимости от того, какая операция была введена.

в конце напечатать результат.

 

Ответьте на следующие вопросы прежде чем приступить к написанию кода:

1. Какой оператор лучше использовать, чтобы проверить, какую операцию выполнять?  (switch)

2. Если пользователь ввёл не поддерживаемую операцию стоит ли ему сообщить об этом? ( проверка ввода .. предупредить об ошибке)

3. Нужна ли дополнительная переменная для второго операнда? А для результата? (operand2 для второго и result для результата)

4.  Можно ли написать весь код в одном методе? или вынести код для каждой операции отдельно? (лучше разнести получение одного, второго операнда и знака операции отдельно, и отдельный метод для расчета)

 

прежде чем решать данную задачу, необходимо разбить задачу на подзадачи. всего есть 3 основных шага:

Шаг №1 вводятся 2 числа  ->> метод getInt()

Шаг №2 выбирается операция ->> метод char getOperation()

Шаг №3 Калькулятор считает ->> метод int calc(int operand1, int operand2, char operation)

поэтому в методе int nextInt() мы прописали механику считывания числа с консоли и проверки целочисленное число введено или нет.

 

public static int nextInt(){
System.out.println("Введите число:");
int operand;
if(scanner.hasNextInt()){
operand = scanner.nextInt();
} else {
System.out.println("Вы допустили ошибку при вводе числа. Попробуйте еще раз.");
scanner.next();//рекурсия
operand = nextInt();
}
return operand;
}

 и потом просто в методе main() вызовем 2 раза метод int nextInt(),

потому что пользователь будет вводить 2 числа.

Обратите внимание, что с помощью конструкции if-else мы прописали, что если число целочисленное, тогда присвоить введенное пользователем значение в переменную operand, если же не целочисленное, - вывести в консоль "Вы допустили ошибку при вводе числа. Попробуйте еще раз".

Также обратите внимание, что мы использовали рекурсию в else:

} else {
System.out.println("Вы допустили ошибку при вводе числа. Попробуйте еще раз.");
scanner.next();//рекурсия
operand = nextInt();
}

 Выбо операции (+ - * /) мы осуществили с помощью метода char getOperation()

public static char getOperation(){
System.out.println("Введите операцию:");
char operation;
if(scanner.hasNext()){
operation = scanner.next().charAt(0);
} else {
System.out.println("Вы допустили ошибку при вводе операции. Попробуйте еще раз.");
scanner.next();//рекурсия
operation = getOperation();
}
return operation;
}

 

 Как видите, пользователю предлагается ввести операцию. А далее программа должна распознать было ли введеное пользователем значение типа char или нет. Причем нас устроит только, если пользователь введет: + - * или / . Например, если пользователь введет число, нас не устроит. Вероно? Поэтому мы применили небольшую хитрость вот в этих 2 строчках кода:

if(scanner.hasNext()){
operation = scanner.next().charAt(0);

 Мы с помощью метода сканера next() считали всю строчку. А далее, поскольку нам не нужна вся строка, а нужен только первый элемент строки, то есть нулевой элемент, поэтому мы вызвали еще и метод charAt(0). И таким образом мы получим только значение 0-го элемента, а не всей строки.

И далее мы прописали сам метод int calc(int operand1, int operand2, int operation):

public static int calc(int operand1, int operand2, char operation){
int result;
switch (operation){
case '+':
result = operand1+operand2;
break;
case '-':
result = operand1-operand2;
break;
case '*':
result = operand1*operand2;
break;
case '/':
result = operand1/operand2;
break;
default:
System.out.println("Операция не распознана. Повторите ввод.");
result = calc(operand1, operand2, getOperation());//рекурсия
}
return result;
}

 Как видите, мы использовали конструкцию switch-case. И прописали, что:

если пользователь ввел +, тогда operand1+operand2, то есть суммируем 2 числа, введенных пользователем.

если пользовательввел -, тогда operand1-operand2, то есть из 1-го числа, введенного пользователем вычитаем 2-е число 

итд

также обратите внимание, что здесь мы тоже использовали рекурсию.

 default:
System.out.println("Операция не распознана. Повторите ввод.");
result = calc(operand1, operand2, getOperation());//рекурсия

и после того как мы прописали все необходимые методы, мы в методе main() прописали следующее:

public static void main(String[] args) {
int operand1 = nextInt();
int operand2 = nextInt();
char operation = getOperation();
int result = calc(operand1,operand2,operation);
System.out.println("Результат операции: "+result);
}

то есть в переменные operand1 и operand2 будут присвоены,

соответственно, 1-е и 2-е число, введенное пользователем.

в переменнную operation будет присвоенна операция, которую ввел пользователь: + - * или / 

далее в переменную result будет присвоен рузультат вычислений нашего калькулятора

и после этого результат будет выведен в консоль



ниже приведем весь код калькулятора

 

import java.util.Scanner;

public class Calculator {
static Scanner scanner = new Scanner(System.in);

public static void main(String[] args) {
int operand1 = nextInt();
int operand2 = nextInt();
char operation = getOperation();
int result = calc(operand1,operand2,operation);
System.out.println("Результат операции: "+result);
}

public static int nextInt(){
System.out.println("Введите число:");
int operand;
if(scanner.hasNextInt()){
operand = scanner.nextInt();
} else {
System.out.println("Вы допустили ошибку при вводе числа. Попробуйте еще раз.");
scanner.next();//рекурсия
operand = nextInt();
}
return operand;
}

public static char getOperation(){
System.out.println("Введите операцию:");
char operation;
if(scanner.hasNext()){
operation = scanner.next().charAt(0);
} else {
System.out.println("Вы допустили ошибку при вводе операции. Попробуйте еще раз.");
scanner.next();//рекурсия
operation = getOperation();
}
return operation;
}

public static int calc(int operand1, int operand2, char operation){
int result;
switch (operation){
case '+':
result = operand1+operand2;
break;
case '-':
result = operand1-operand2;
break;
case '*':
result = operand1*operand2;
break;
case '/':
result = operand1/operand2;
break;
default:
System.out.println("Операция не распознана. Повторите ввод.");
result = calc(operand1, operand2, getOperation());//рекурсия
}
return result;
}
}

 


пятница, 7 февраля 2020 г.

Округление в OpenOffice Calc

Округление  в OpenOffice Calc

Для округления в OpenOffice Calc имеются две функции: CEILING(число; приращение; режим), FLOOR(число; точность; режим), которые являются аналогами ОКРУГЛВВЕРХ и ОКРУГЛВНИЗ в Excel . CEILING - округляет число в большую сторону, FLOOR - в меньшую. Параметр режим является необязательным, но для лучшей совместимости с Excel рекомендуется ставить 1. Второй параметр в этих функциях задает точность округления и может быть любой, например: 0,5 - до половины; 0,25 - до четверти; 0,75 - до трех четвертей; 1- до единицы 0,01 до двух знаков после запятой и тд.. 
Также в функции CEILING параметр приращение  еще работает и как  условие:но_не_менее, и CEILING(3,245436674; 5; 1) вернет значение 5.

воскресенье, 9 июля 2017 г.

заметка ssh открывалка

простейший portknock'ер работающий по icmp
-A INPUT -p icmp --icmp-type 8 -m length --length 153 -m recent --name pk --rsource --set -j ACCEPT
-A INPUT -p icmp --icmp-type 8 -m length --length 154 -m recent --name pk --rsource --update --hitcount 1 -j ACCEPT
-A INPUT -p icmp --icmp-type 8 -m length --length 155 -m recent --name pk --rsource --update --hitcount 2 -j ACCEPT
-A INPUT -p tcp --dport 22 -m recent --name pk --rsource --rcheck -j ACCEPT
-A INPUT -p tcp --dport 22 -j DROP
для того чтобы открыть 22 порт достаточно и необходимо
ping -s 125 -c 1 адрес
ping -s 126 -c 1 адрес
ping -s 127 -c 1 адрес
количество пакетов регулируется через --hitcount
сами числа передаются через длину icmp-echo
хорош тем что инструмен "стучания" обычно доступен

понедельник, 16 января 2017 г.

Установка Squid 3.5.19 на Ubuntu 14.04.5 LTS с поддержкой HTTPS протокола

Первым делом обновляем систему до актуального состояния
sudo apt-get update
sudo apt-get upgrade
Устанавливаем необходимые для сборки пакетов инструменты
sudo apt-get -y install devscripts build-essential fakeroot debhelper dh-autoreconf cdbs
Устанавливаем зависимости для libecap и squid
sudo apt-get -y build-dep libecap
sudo apt-get -y build-dep squid3
Удаляем старую версию libecap
sudo apt-get -y --purge remove libecap2-dev libecap2
Устанавливаем необходимые дополнительные пакеты для сквида
sudo apt-get -y install nettle-dev libgnutls28-dev libssl-dev libdbi-perl
Создаем папки где будем собирать libecap (чтобы не захламлять home)
mkdir -p build/libecap
Перейдем в созданный каталог
pushd build/libecap
Скачиваем исходники libecap3
wget http://jakondo.ru/wp-content/uploads/file-manager/squid_3.5.19/libecap_1.0.1-3.dsc
wget http://jakondo.ru/wp-content/uploads/file-manager/squid_3.5.19/libecap_1.0.1.orig.tar.gz
wget http://jakondo.ru/wp-content/uploads/file-manager/squid_3.5.19/libecap_1.0.1-3.debian.tar.xz
Распаковываем
sudo dpkg-source -x libecap_1.0.1-3.dsc
Открываем текстовым редактором файл libecap-1.0.1/debian/control
sudo nano libecap-1.0.1/debian/control
находим строку
Build-Depends: debhelper (>= 8.0.0), autotools-dev, cdbs, dh-autoreconf, g++ (>= 4:5.2)
и заменяем ее на
Build-Depends: debhelper (>= 8.0.0), autotools-dev, cdbs, dh-autoreconf
Сохраняем документ и выходим
Ctrl+O, Ctrl+X
Входим в каталог
cd libecap-1.0.1
И запускаем процесс создания пакета
sudo dpkg-buildpackage -rfakeroot -b
Выходим из каталога
popd
Теперь установим полученные в ходе сборки пакеты. Войдем в каталог где они у нас сформировались
pushd build/libecap
Установим пакеты
sudo dpkg --install libecap3_1.0.1-3_amd64.deb
sudo dpkg --install libecap3-dev_1.0.1-3_amd64.deb
Выходим из каталога
popd
Теперь перейдем к основной нашей цели, это сборка и установка Squid 3.5.19.
Создадим каталог где мы будем собирать Squid
mkdir -p build/squid3
Перейдем в созданный каталог
pushd build/squid3
Скачаем исходники
wget http://jakondo.ru/wp-content/uploads/file-manager/squid_3.5.19/squid3_3.5.19-1.dsc
wget http://jakondo.ru/wp-content/uploads/file-manager/squid_3.5.19/squid3_3.5.19.orig.tar.gz
wget http://jakondo.ru/wp-content/uploads/file-manager/squid_3.5.19/squid3_3.5.19-1.debian.tar.xz
Распакуем исходный пакет
sudo dpkg-source -x squid3_3.5.19-1.dsc
Отредактируем файл правила сборки пакета rules. А конкретней добавим необходимые нам компоненты, для работы с HTTPS трафиком
sudo nano squid3-3.5.19/debian/rules
Ищем строку
--with-default-user=proxy
и вместо нее пишем
--with-default-user=proxy \
--with-openssl \
--enable-ssl \
--enable-ssl-crtd
Сохраняем документ и выходим
Ctrl+O, Ctrl+X
Перейдем в каталог для запуска сборки пакета
cd squid3-3.5.19
И запустим процесс сборки пакета Squid. (Процесс довольно продолжительный)
sudo dpkg-buildpackage -rfakeroot -b
После того как сборка пакета завершилась, выходим из каталога.
popd
Все готово для установки Squid. Перейдем в каталог где у нас находятся собранные пакеты Squid
pushd build/squid3
Сперва установим Squid langpack, чтобы была поддержка русского языка
sudo apt-get install squid-langpack
Устанавливаем пакеты Squid в очередности как указано ниже.
sudo dpkg --install squid-common_3.5.19-1_all.deb
sudo dpkg --install squid_3.5.19-1_amd64.deb
sudo dpkg --install squidclient_3.5.19-1_amd64.deb
Выходим из каталога.
popd
На этом установка Squid 3.5.19 завершена. Теперь нужно выполнить настройку его, создать сертификат для работы с HTTPS трафиком.
Файл конфигурации Squid находится /etc/squid/squid.conf. Файл огромный, главный его плюс это то что он очень хорошо комментирован, но редактирование его для меня не совсем удобное, поэтому я создаю бекап дефолтного файла конфигурации, удаляю оригинал и создаю новый текстовый файл в котором будем прописывать только нужные нам параметры для работы Squid. Поехали..
Создаем бекап дефолтного файла
sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.backup
Удаляем оригинальный файл конфигурации
sudo rm /etc/squid/squid.conf
И создаем новый файл будущей конфигурации
sudo nano /etc/squid/squid.conf
Небольшое отступление перед написанием конфигурации. Файл конфигурации может быть различным и для каждого места индивидуальным. Я опишу свою схему работы Squid и напишу какой в итоге у меня получился конфиг.
Организация сети и получение интернета. Имеется роутер Mikrotik, в который приходит интернет, так же на этом роутере развернут DHCP, локальная подсеть 192.168.5.0/24. В этой же подсети находится и нас свеже установленный Squid, с адресом 192.168.5.2Squid будет у нас работать в обычном режиме. (В идеале хотелось бы конечно работать по прозрачному протоколу, но как только не пытался, не удается завернуть трафик с Mikrotik на Squid на прозрачные порты 80443, поэтому я остановился на работе по обычному режиму работы Squid).
Желаемая работа Squid будет заключаться в раздаче интернета только в пределах локальной сети 192.168.5.0/24, а так же возможность блокировать любые неугодные нам сайты для пользователей, возможность блокировать доступ в интернет за исключением белого списка адресов сайтов, ну и конечно создать группу определенных адресов, которых не будут касаться никакие запреты.
В итоге моего плана у меня получился вот такой конфигурации
######################################
# Обслуживаемые прокси-сервером сети #
######################################
acl localnet src 192.168.5.0/24
#################################################
# Правила какие порты разрешены прокси-сервером #
#################################################
# Порт SSL для подключений по HTTPS-протоколу
acl SSL_ports port 443
# Список портов, к которым разрешен доступ через прокси-сервер по протоколу HTTP
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
################################################################
# Пути к файлам запрещающих, разрешающих определенные действия #
################################################################
# Путь к списку IP-адресов пользователей, для которых не действуют запреты
acl AdminsIP src "/etc/squid/AdminsIP.txt"
# Путь к черному списку сайтов
acl BlackList dstdomain "/etc/squid/BlackList.txt"
# Путь к списку адресов которым запрещен интернет
acl BlockInetExlWhite src "/etc/squid/BlockInetExlWhite.txt"
# Путь к белому списку сайтов
acl WhiteList dstdomain "/etc/squid/WhiteList.txt"
#########################
# Параметры DNS записей #
#########################
# Список DNS серверов(IP адреса), которые будут использоваться вместо тех, что определены в /etc/resolv.conf файле
dns_nameservers 192.168.5.3
########################################
# Правила ограничений доступа клиентов #
########################################
# Запретить доступ к портам, отсутствующим в списке выше
http_access deny !Safe_ports
# Запретить метод CONNECT не на SSL-порт
http_access deny CONNECT !SSL_ports
# Разрешить только локальное управление кэшем
http_access allow localhost manager
http_access deny manager
# Не ограничивать локальный доступ с сервера
http_access allow localhost
# Не ограничивать доступ администраторам
http_access allow AdminsIP
# Блокировать интернет конкретным пользователям
http_access deny BlockInetExlWhite !WhiteList
# Блокировать запрещенные сайты
http_access deny BlackList
# Правила разрешающего доступ в интернет из локальной сети указанной в localnet
http_access allow localnet
# Блокирует все, что не было разрешено выше
http_access deny all
#############################################
# Правила подключений клиентов к прокси-серверу#
#############################################
# Подключения через прозрачный порт
http_port 192.168.5.2:3128 intercept options=NO_SSLv3:NO_SSLv2
# Подключение через указания прокси-сервера на стороне клиента
http_port 192.168.5.2:3130 options=NO_SSLv3:NO_SSLv2
# Подключение по HTTPS через прозрачный порт с параметрами подставки сертификата
https_port 192.168.5.2:3129 intercept ssl-bump options=ALL:NO_SSLv3:NO_SSLv2 connection-auth=off cert=/etc/squid/squidca.pem
# Принимаем сертификаты, даже если они не прошли проверку.
always_direct allow all
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
# Укажем список блокируемых ресурсов (в файле домены вида .domain.com) и правила блокировки их
acl blocked ssl::server_name "/etc/squid/BlackList.txt"
# Устанавливаем защищенное соединение и считываем заголовок HTTP
acl step1 at_step SslBump1
ssl_bump peek step1
# Закрываем соединение, если клиент заходит на ресурс указанные в blocked
ssl_bump terminate blocked
ssl_bump splice all
sslcrtd_program /usr/lib/squid/ssl_crtd -s /var/lib/ssl_db -M 4MB
#########################################
# Дополнительные параметры конфигурации #
#########################################
# Путь для дискового кеширования
cache_dir aufs /var/spool/squid 20000 49 256
# Путь сохранения дампов аварийного завершения
coredump_dir /var/spool/squid
# Время жизни объектов для протоколов FTP и GOPHER
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
# Нулевое время жизни для динамического контента
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
# Время жизни по умолчанию
refresh_pattern . 0 20% 4320
maximum_object_size 61440 KB
minimum_object_size 3 KB
cache_swap_low 90
cache_swap_high 95
# Максимальный размер объекта, сохраняемого в оперативной памяти
maximum_object_size_in_memory 512 KB
memory_replacement_policy lru
# Количество ротаций лог-файлов (0 - отключена ротация, 15 - максимальное количество)
logfile_rotate 0
# E-mail адрес Cache менеджера, для отправки уведомлений и отображении в страницах ошибок
cache_mgr it@admin.ru
После того как конфиг Squid готов, нужно создать сертификат для работы с HTTPS протоколом
sudo openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -keyout squidca.pem -out squidca.pem
Сертификат создан, почти все готово. Переместим созданный сертификат в папку Squid
sudo mv squidca.pem /etc/squid/squidca.pem
Т.к. в конфиге мы указывали правила по блокировки сайтов, создание белого списка сайтов и т. д. нам нужно создать эти файлы и по необходимости заполнить их, создаем
sudo touch /etc/squid/AdminsIP.txt — Список IP адресов без ограничений
sudo touch /etc/squid/BlackList.txt — Список блокированных сайтов (прим.: .mail.ru)
sudo touch /etc/squid/BlockInetExlWhite.txt - Список IP адресов которым запрещен интернет кроме белого списка
sudo touch /etc/squid/WhiteList.txt — Список белых сайтов для посещения (прим.: .jakondo.ru)
После того как заполнили все необходимые списки, торжественно запускаем Squid
sudo service squid start
Проверим статус работы запущенного нами Squid
sudo service squid status
Если видим сообщение — * squid is running, то все отлично Squid работает успешно. Если же иная запись с надписью Failed, то смотрите вывод статуса, всегда пишет в чем проблема, исправляем ошибку и снова пробуем запустить.
В моем случае осталось прописать на ПК пользователей в Свойствах обозревателя, параметры прокси-сервера и проверить работу. Если все было сделано как по инструкции то все будет работать правильно.
Так же можно посмотреть работу Squid в режиме реального времени выполнив команду
sudo taild -f /var/log/squid/access.log