C# соль и хеш паролей.

Нашел на cyberforum.ru вот такой класс для хешрования паролей с солью.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;

namespace ppo_admin
{
    class Password
    {
        private byte[] _salt;       // синхропосылка
        private byte[] _hash;       // хэш пароля
        /*все четыре свойства просто возвращают значения
         * соответствующих полей объекта
         */
        internal string Salt
        {
            get { return Convert.ToBase64String(_salt); }
        }

        internal string Hash
        {
            get { return Convert.ToBase64String(_hash); }
        }

        internal byte[] RawSalt
        {
            get { return (byte[])_salt.Clone(); }
        }

        internal byte[] RawHash
        {
            get { return (byte[])_hash.Clone(); }
        }
        internal Password(string salt, string hash)
        {
            /*Конструктор с двумя строковыми аргументами
             * просто преобразует синхропосылку и хэш из base64
             * в двоичное представление и сохраняет в
             * соответствующих полях класса
             * В конструктор передаем полученную соль и хэш пароля
             */
            _salt = Convert.FromBase64String(salt);
            _hash = Convert.FromBase64String(hash);
        }
        internal Password(byte[] salt, byte[] hash)
        {
            /*Конструктор, принимающий массивы байт,
             * создает копии входных массивов
             * В конструктор передаем полученную соль и хэш пароля
             */
            _salt = (byte[])salt.Clone();
            _hash = (byte[])hash.Clone();
        }
        internal Password(char[] clearText)
        {
            /*Генерация соли и пароля
             * Конструктор с одним аргументом генерирует
             * случайную синхропосылку и вычисляет хэш
             * предоставленного пароля, используя внутренний
             * метод HashPassword()
             */
            _salt = GenerateRandom(6);
            _hash = HashPassword(clearText);
        }
        /*Метод Verify сначала вычисляет хэш предоставленного
         * пароля, используя все тот же внутренний метод
         * HashPassword, после чего сравнивает байты сохраненного
         * хэша с байтами только что вычисленного хэша. Совпадение
         * всех до одного байтов хэша означает, что пароль верный.
         */

        /// 
<summary>
        /// 
        /// </summary>

        /// <param name="clearText">Передаем введенный пароля для проверки.</param>
        /// <returns>Возвращаем если все ок. или не ок</returns>
        internal bool Verify(char[] clearText)
        {
            byte[] hash = HashPassword(clearText);

            if (hash.Length == _hash.Length)
            {
                for (int i = 0; i < hash.Length; i++)
                {
                    if (hash[i] != _hash[i])
                        return false;
                }

                return true;
            }

            return false;
        }
        /*Статический метод Generate просто генерирует
         * массив случайных байтов и преобразует его
         * в base64-строку.
         */
        private static char[] Generate()
        {
            char[] random = new char[12];

            // генерируем 9 случайных байтов; этого достаточно, чтобы
            // получить 12 случайных символов из набора base64
            byte[] rnd = GenerateRandom(9);

            // конвертируем случайные байты в base64
            Convert.ToBase64CharArray(rnd, 0, rnd.Length, random, 0);

            // очищаем рабочий массив
            Array.Clear(rnd, 0, rnd.Length);

            return random;
        }
        /* Метод записывает синхропосылку и пароль в поток на
         * основе массива байтов, а затем вычисляет хэш
         * содержимого потока. В качестве хэш-функции используется
         * алгоритм SHA-256.
         */
        private byte[] HashPassword(char[] clearText)
        {
            Encoding utf8 = Encoding.UTF8;
            byte[] hash;

            // создаем рабочий массив достаточного размера, чтобы вместить
            byte[] data = new byte[_salt.Length
                        + utf8.GetMaxByteCount(clearText.Length)];

            try
            {
                // копируем синхропосылку в рабочий массив
                Array.Copy(_salt, 0, data, 0, _salt.Length);

                // копируем пароль в рабочий массив, преобразуя его в UTF-8
                int byteCount = utf8.GetBytes(clearText, 0, clearText.Length,
                  data, _salt.Length);

                // хэшируем данные массива
                using (HashAlgorithm alg = new SHA256Managed())
                    hash = alg.ComputeHash(data, 0, _salt.Length + byteCount);
            }
            finally
            {
                // очищаем рабочий массив в конце работы, чтобы избежать
                // утечки открытого пароля
                Array.Clear(data, 0, data.Length);
            }

            return hash;
        }
        /*Метод GenerateRandom генерирует массив указанной длины,
         * состоящий из случайных байтов.
         */
        private static byte[] GenerateRandom(int size)
        {
            byte[] random = new byte[size];
            RandomNumberGenerator.Create().GetBytes(random);
            return random;
        }
    }
}

Для генерации паролей создаем форму

    public partial class GeneratePassword : Form
    {
        Password pwd;

        public GeneratePassword()
        {
            InitializeComponent();
        }

        private void btExit_Click(object sender, EventArgs e)
        {
            this.Close();

        }

        private void btGenerate_Click(object sender, EventArgs e)
        {
            //tbNewPassword - textBox для ввода пароля
            //tbSalt        - textBox для вывода сгенерированной соли
            //tbHash        - textBox для вывода сгенерированного пароля
            pwd = new Password(tbNewPassword.Text.ToCharArray());
            tbSalt.Text = pwd.Salt;
            tbHash.Text = pwd.Hash;
        }
    }

Для проверки валидности пароля надо передать соль и хеш.

                SqlConnection con = new SqlConnection(@"Data Source=(localdb)\MyInstance;Initial Catalog=DBase;Integrated Security=true ");
                SqlDataAdapter sda = new SqlDataAdapter("Select * From tb_Users where UserName='" + tbLogin.Text + "'", con);
                DataTable dt = new DataTable();
                sda.Fill(dt);
                if (dt.Rows[0][0] != null)
                {
                    string id   = dt.Rows[0][0].ToString().Trim();
                    string user = dt.Rows[0][1].ToString().Trim();
                    string salt = dt.Rows[0][2].ToString().Trim();
                    string hash = dt.Rows[0][3].ToString().Trim();
                    Password pwd = new Password(salt, hash);
                    if (pwd.Verify(tbPassword.Text.ToCharArray()))
                    {
                        MainForm MainFrm = new MainForm();
                        FormEditUsers edtuser = new FormEditUsers();
                        edtuser.dbstring = "local";
                        MainFrm.Show();
                        this.Hide();
                    }
                    else
                    {
                        MessageBox.Show("Invalide password!");
                    }
                }

Структура таблицы такая

CREATE TABLE [dbo].[tb_Users] (
    [Id]       INT        NOT NULL,
    [UserName] NCHAR (10) NULL,
    [Salt]     NCHAR (10) NULL,
    [Hash]     NCHAR (55) NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

MS Visual Studion и SQL.

Не знаю у кого как а у меня студия установилась вместе с SQL сервером. Как его полноценно обозвать не знаю. Но работать можно так.
Запускаем cmd.exe и пишем:
>sqllocadb i
в ответ получаем
MyInstance
Projects
v11.0
Кому как удобней но я создал новый инстанс и работаю с ним
>sqllocaldb create «MyInstance» — создать
>sqllocaldb start «MyInstance» — запустить
или можно все в одной команде
>sqlLocaldb create «MyInstance» -s — создать и запустить
До недавнего времени я работал так. Запускал комп делал
>sqllocaldb start «MyInstance» — запустить
>sqllocaldb i «MyInstance» — посмотреть информацию
Name: MyInstance
Version: 11.0.3000.0
Shared name:
Owner: 71HP2540P
Auto-create: No
State: Running
Last start time: 20.12.2016 16:57:27
Instance pipe name: np:\\.\pipe\LOCALDB#996B35E3\tsql\query
Копировал строку \\.\pipe\LOCALDB#996B35E3\tsql\query и вставлял ее везде где были подключения к бд. Жутко не удобно. Где то прочитал что можно делать так, не копировать пайп а просто в стоке подключения писать (localdb)\MyInstance

raspberry pi and wpa_cli

/etc/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=/run/wpa_supplicant
update_config=1

# wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf

wpa_cli
> scan
> scan_result
> add_network
0
> set_network 0 ssid «MYSSID»
> set_network 0 psk «passphrase»
> enable_network 0
или если открытая сеть то
> set_network 0 ssid «MYSSID»
> set_network 0 key_mgmt NONE
> enable_network 0
> save_config
#dhcpd wlan0

Источник

C# и локальные отчеты (MVS2013)

Создадим новый проект.
Разместить на форме
добавить в проект Report
добавить в проект Report
На Report добавить параметр
На Report добавить параметр
На Report добавить параметр
На Report добавить TextBox
На Report добавить TextBox
Событию нажатия кнопки написать
Запустить и ввести имя
Нажать кнопку

 private void button1_Click(object sender, EventArgs e)
        {
            reportViewer1.LocalReport.ReportPath = "..\\..\\Report1.rdlc";
            reportViewer1.LocalReport.SetParameters(new Microsoft.Reporting.WinForms.ReportParameter("NameUser", textBox1.Text));
            this.reportViewer1.RefreshReport();
        }

C#. Работа с DataSet, DataTable без подключения к БД. Часть 1.

Создание DataSet и вставка в него объектов, состоит в следующем:
1. Создание DataSet
2. Создание DataTable
3. Создание DataColumn
4. Добавление DataColumn в DataTable
5. Создание DataRow
6. Добавление DataRow в DataTable
7. Добавление DataTable в DataSet

1. Создание DataSet
Создаем проект, на форму добавляем DataGridView1.
В обработке событий формы Form1_Load пишем:

//1. Создаем DataSet с названием dsetUsers
DataSet dset = new DataSet("dsetUsers"); 

//2. Создаем DataTable с названием user
DataTable dtable = new DataTable("user"); //DataTable

//3. Создаем колонки для таблицы id name surnamr age
DataColumn id = new DataColumn("id", typeof(int));
id.Unique = true; //id уникальное
id.AutoIncrement = true; //Автоинкремент - полю присваивается значение автоматически
id.AutoIncrementSeed = 1; //
id.AutoIncrementStep = 1; //Шаг автоинкремента
DataColumn name = new DataColumn("name", typeof(string));
DataColumn surname = new DataColumn("surname", typeof(string));
DataColumn age = new DataColumn("age", typeof(int));

//4. Добавление DataColumn в DataTable
dtable.Columns.AddRange(new DataColumn[] { id, name, surname, age });

//5. Создание DataRow
DataRow row = dtable.NewRow();
row["name"] = "Vasya";
row["surname"] = "Pupkin";
row["age"] = 5;

DataRow row1 = dtable.NewRow();
row1[1] = "Misha";
row1[2] = "Pupkin";
row1[3] = 23;

//6. Добавление DataRow в DataTable
dtable.Rows.Add(row);
dtable.Rows.Add(row1);

7. Добавление DataTable в DataSet
dset.Tables.Add(dtable);


dataGridView1.DataSource = dset.Tables[0];
//dataGridView1.DataSource = dset.Tables["users"];

Контроль наличия 220 В

Оптопара pc814 + резистор на 56кОм 1w
pc814 имеет два фоторезистора и не требует диодного моста в отличии от pc817
Схема подключения
detektornylyashema
По схеме R1 можно брать любой от 56кОм до 100кОм — проверено.
Я нуб и не сразу понял что да как. На 4 контакт подается +5 вольт от Arduino через резистор R2 (10кОм) или не обязательно +5 от ардуины. А уже после резистора R2 снимаем сигнал 1 или 0.

Заметки о MySQL

SHOW DATABASES; посмотреть название бд
SHOW COLUMNS FROM tbTest; посмотреть какие поля в таблице
SELECT * FROM tbTest; посмотреть записи в таблице

Использовать uuid. Автоинкремент не включать.
CREATE TABLE tbTest(
uuid VARCHAR(36) NOT NULL PRIMARY KEY,
City VARCHAR(25)
);

CREATE TRIGGER название_триггера BEFORE INSERT ON название_таблицы FOR EACH ROW NEW.поле=UUID();
или
CREATE TRIGGER `название_триггера` BEFORE INSERT ON `название_таблицы` FOR EACH ROW SET NEW.поле=uuid()

MySQL and C++

Для того что бы все заработало необходимо скачать следующее:
1. mysql-5.7.14-win32.zip
2. mysql-connector-c++-1.1.7-win32.msi (или mysql-connector-c++-noinstall-1.1.7-win32.zip)
3. boost
Все скаченное сохраняем в папку, для удобства c:\mysql_cpp. Создаем две папки include и lib\opt

В папку c:\mysql_cpp\include копируем все из C:\Program Files (x86)\MySQL\MySQL Connector C++ 1.1.7\include
В папку c:\mysql_cpp\lib\opt копируем все из C:\Program Files (x86)\MySQL\MySQL Connector C++ 1.1.7\lib\opt
Из архива mysql-5.7.14-win32.zipmysql-5.7.14-win32.zip\mysql-5.7.14-win32\lib копируем libmysql.lib в папку c:\mysql_cpp\lib\opt

Теперь необходимо настроить проект. Создадим консольное приложение mysql.
Идем в настройки проекта:
C\C++ — General — Additional Include Directories = c:\mysql_cpp\include
C\C++ — General — Additional Include Directories = c:\Путь\до\boost

C\C++ — General — Preprocessor = добавить CPPCONN_PUBLIC_FUNC=

C\C++ — Code Generator — Runtime Library = /MT

Linker — General — Additional Library Directories = c:\mysql_cpp\lib\opt
Linker — Input — Additional Dependencies = добавить mysqlcppconn-static.lib; libmysql.lib;

Сохранить изменения.

#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
/* uncomment for applications that use vectors */
/*#include <vector>*/
#include <stdlib.h>
#include <Windows.h>
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include "mysql_connection.h"
#include "mysql_driver.h"
//#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
//#pragma comment(lib,"libmysql.lib")
//#pragma comment(lib,"mysqlcppconn.lib")
using namespace std;
using namespace sql;

int _tmain(int argc, _TCHAR* argv[])
{
	sql::Connection *con;
	sql::Statement *stmt;
	sql::mysql::MySQL_Driver *driver;
	driver = sql::mysql::get_driver_instance();
	con = driver->connect("tcp://192.168.1.128", "root", "qwerty");
	stmt = con->createStatement();
	stmt = con->createStatement();
	stmt->execute("USE DBUSER");
	stmt->execute("DROP TABLE IF EXISTS test");
	stmt->execute("CREATE TABLE test(id INT, label CHAR(1))");
	stmt->execute("INSERT INTO test(id, label) VALUES (1, 'a')");
	delete stmt;
	delete con;
	return 0;
}
Запись опубликована автором в рубрике C++.