Author Archive

Получение MD5 хэша на Java

Первый вариант (которым я пользуюсь):
public static final String md5(final String text){
	try{
		MessageDigest md = MessageDigest.getInstance("MD5");
		md.update(text.getBytes());
		String hash = new BigInteger(1, md.digest()).toString(16);
		while(hash.length() < 32) hash = "0" + hash;
		return hash;
	}catch(NoSuchAlgorithmException e){
		e.printStackTrace();
	}
	return "";
}
Второй вариант:
public static final String md5(final String s) {
    try {
        // Create MD5 Hash
        MessageDigest digest = java.security.MessageDigest
                .getInstance("MD5");
        digest.update(s.getBytes());
        byte messageDigest[] = digest.digest();

        // Create Hex String
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < messageDigest.length; i++) {
            String h = Integer.toHexString(0xFF & messageDigest[i]);
            while (h.length() < 2)
                h = "0" + h;
            hexString.append(h);
        }
        return hexString.toString();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "";
}

Сортировка слиянием на Java

Реализация сортировки слиянием на Java:
//рекурсивная функция сортировки частей массива
public static int[] sort(int[] arr){
	if(arr.length < 2) return arr;
	int m = arr.length / 2;
	int[] arr1 = Arrays.copyOfRange(arr, 0, m);
	int[] arr2 = Arrays.copyOfRange(arr, m, arr.length);
	return merge(sort(arr1), sort(arr2));
}
//слияние двух массивов в один отсортированный
public static int[] merge(int[] arr1,int arr2[]){
	int n = arr1.length + arr2.length;
	int[] arr = new int[n];
	int i1=0;
	int i2=0;
	for(int i=0;i
Пример использования:
int[] arr ={2,1,0,6,1,9,8,7};//тестовый массив
System.out.println(Arrays.toString(arr));//вывод на экран исходного массива
int[] sortArr = sort(arr);//сортировка
System.out.println(Arrays.toString(sortArr));//вывод на экран отсортированного массива

Простые числа (Решето Эратосфена)

Нахождение простых чисел методом "Решето Эратосфена" Реализация на Java:
public class Primes {

	private boolean primes[];

	public Primes(int number){
		primes = new boolean[number+1];		
		Arrays.fill(primes, true);
		primes[0] = false;
		primes[1] = false;
		for(int i = 2;i*i < number;i++){
			if(primes[i]){
				for(int j=i*i;j < number;j+=i){
					primes[j] = false;
				}
			}
		}
		
	}
	
	public boolean check(int number){
		return primes[number];
	}

}
Применение:
int N = 100;
Primes primes = new Primes(N);
for(int i=0;i            

ArrayUtils — методы по работе с массивами

Методы по работе с массивами
public class ArrayUtils {

	//сумма элементов int массива
	public static int sum(int[] arr){
		int sum = 0;
		for(int i : arr) sum += i;
		return sum;
	}

	//сумма элементов long массива	
	public static long sum(long[] arr){
		long sum = 0;
		for(long l : arr) sum += l;
		return sum;
	}
	
	//сумма элементов double массива	
	public static double sum(double[] arr){
		double sum = 0;
		for(double d : arr) sum += d;
		return sum;
	}

	//максимальный элемент в int массива
	public static int max(int[] arr){
		int max = Integer.MIN_VALUE;
		for(int i : arr) if(i > max) max = i;
		return max;
	}
	
	//максимальный элемент в long массиве
	public static long max(long[] arr){
		long max = Long.MIN_VALUE;
		for(long l : arr) if(l > max) max = l;
		return max;
	}
	
	//максимальный элемент в double массиве
	public static double max(double[] arr){
		double max = Double.MIN_VALUE;
		for(double d : arr) if(d > max) max = d;
		return max;
	}

	//минимальный элемент в int массиве
	public static int min(int[] arr){
		int min = Integer.MAX_VALUE;
		for(int i : arr) if(i < min) min = i;
		return min;
	}
	
	//минимальный элемент в long массиве
	public static long min(long[] arr){
		long min = Long.MAX_VALUE;
		for(long l : arr) if(l < min) min = l;
		return min;
	}
	
	//минимальный элемент в double массиве
	public static double min(double[] arr){
		double min = Double.MAX_VALUE;
		for(double d : arr) if(d < min) min = d;
		return min;
	}

	//индекс максимального элемента в int массиве
	public static int maxIndex(int[] arr){
		int p = -1;
		int len = arr.length;
		if(len > 0){
			p = 0;
			for(int i = 1; i < len; i++) 
				if(arr[i] > arr[p]) 
					p = i;
		}
		return p;
	}
	
	//индекс максимального элемента в long массиве
	public static int maxIndex(long[] arr){
		int p = -1;
		int len = arr.length;
		if(len > 0){
			p = 0;
			for(int i = 1; i < len; i++)
				if(arr[i] > arr[p])
					p = i;
		}
		return p;
	}
	
	
	//индекс максимального элемента в double массиве
	public static int maxIndex(double[] arr){
		int p = -1;
		int len = arr.length;
		if(len > 0){
			p = 0;
			for(int i = 1; i < len; i++)
				if(arr[i] > arr[p])
					p = i;
		}
		return p;
	}

	//индекс минимального элемента в int массиве
	public static int minIndex(int[] arr){
		int p = -1;
		int len = arr.length;
		if(len > 0){
			p = 0;
			for(int i = 1; i < len; i++) 
				if(arr[i] < arr[p]) 
					p = i;
		}
		return p;
	}
	
	//индекс минимального элемента в long массиве
	public static int minIndex(long[] arr){
		int p = -1;
		int len = arr.length;
		if(len > 0){
			p = 0;
			for(int i = 1; i < len; i++)
				if(arr[i] < arr[p])
					p = i;
		}
		return p;
	}
	
	
	//индекс минимального элемента в double массиве
	public static int minIndex(double[] arr){
		int p = -1;
		int len = arr.length;
		if(len > 0){
			p = 0;
			for(int i = 1; i < len; i++)
				if(arr[i] < arr[p])
					p = i;
		}
		return p;
	}


}

FileUtils — Сборка методов по работе с файлами

Метод считывает все строки из переданного файла, добавляет их в List<String> и возвращает этот List
public static List getStringList(String fileName) throws IOException{
	BufferedReader br = null;
	List list = new ArrayList();
	String str;
	try{
		br = new BufferedReader(new FileReader(fileName));
		while( (str = br.readLine()) != null ){
			list.add(str);
		}
	}finally{
		if(br != null) br.close();
	}
	return list;
}

Получить все строки файла в виде List<String> (чтение в UTF-8)
public static List getFileLines(String fileName) throws IOException {
	List list = new ArrayList();
	BufferedReader br = null;
	try{
		br = new BufferedReader(
				new InputStreamReader(
						new FileInputStream(fileName),"UTF-8"));
		String str;
		while( (str = br.readLine()) != null ){
			list.add(str);
		}
	}finally {
		if(br != null)
			br.close();
	}
	return list;
}

Получение байтов файла по URL
public static byte[] downloadFile(URL url) throws IOException {
	byte[] bytes = null;
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	InputStream is = null;
	try {
		is = url.openStream();
		int ch;
		while( (ch = is.read()) != - 1){
			baos.write((byte)ch);
		}
		baos.flush();
		bytes = baos.toByteArray();
		return bytes;
	} finally {
		baos.close();
		if(is != null)is.close();
	}
}

Запись переданных строк в файл в кодировке UTF-8
public static void writeToFile(String fileName,List lines)
		throws IOException{
	BufferedWriter bw = new BufferedWriter(
		new OutputStreamWriter(new FileOutputStream(fileName),"UTF-8"));
	for(String str : lines){
		bw.append(str).append("\n");
	}
	bw.close();
}

Запись String, StringBuilder, StringBuffer в файл (UTF-8)
public static void writeToFile(String fileName,CharSequence charSequence)
		throws IOException{
	BufferedWriter bw = new BufferedWriter(
		new OutputStreamWriter(
			new FileOutputStream(fileName),"UTF-8"));
	bw.append(charSequence);
	bw.close();
}

Перенос директории с данными MySQL (на примере RedHat)

По умолчанию MySQL хранит файлы базы данных на том же диске, где он установлен, и часто требует перенос этих файлов на другой диск большей вместимости. Допустим, у нас имеется RedHat с установленным MySQL 1) Проверим настройки MySQL, вызовем команду:
cat /etc/my.cnf
Получим примерно следующие данные:
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
max_allowed_packet = 500M
default-storage-engine=innodb
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
В файле конфигурации параметр datadir указывает на место хранения файлов базы данных. В нашем случае он указывает на /var/lib/mysql 2) Для проведения переноса данных, первым делом, нужно остановить MySQL.
service mysqld stop
3) Определимся с целевой директорией, куда будет осуществлен перенос. Допустим, мы хотим перенести директорию mysql в директорию /600g
У меня фантазии не хватило - я назвал диск по его размеру.
Пример из жизни: на одном сервере диск в 600 гигабайт я назвал /600g, 
на другом диск в 3 терабайта - назвал /3t
Создадим директорию:
mkdir /600g
4) Теперь скопируем саму папку с содержимым с помощью команды:
cp -R -p /var/lib/mysql /600g
Где cp - стандартная команда для копирования. Стоит обратить внимание на ее параметры: -R - говорит о том, что нужно копировать директорию рекурсивно (включая поддиректории и файлы в поддиректориях) -p - копирование с сохранением всех прав доступа и разрешений /var/lib/mysql - здесь указывается переносимая директория /600g - место, куда будет перенесена директория После переноса директории mysql в /600g, мы получим следующий путь:
/600g/mysql
5) Осталось изменить конфигурацию:
nano /etc/my.cnf
Замените строки, указав на новый путь размещения директории:
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
на следующие:
datadir=/600g/mysql
socket=/600g/mysql/mysql.sock
6) К сожалению, это не все. Нужно еще заменить пути в файле демона: /etc/init.d/mysqld 7) Запускаем MySQL
service mysqld start
8) После переноса появиться еще одна проблема, и пока не знаю как ее исправить. Если у вас на этом же сервере есть клиент MySQL и вы могли его раньше запускать следующим образом:
mysql -uroot -p
То сейчас нужно еще будет явно указывать расположение файла сокета:
mysql -uroot -p --socket=/600g/mysql/mysql.sock
Скорее всего, где то в настройках еще нужно переписать путь. Как в следующий раз появиться возможность произвести подобный перенос, разберусь с этой проблемной. А экспериментировать с боевым сервером не комильфо.

Разметка 3-х терабайтного жесткого диска (Red Hat Linux 6.2)

Расскажу о своем опыте подключения к RedHat 3-х терабайтного жесткого диска. Под наш проект выделили новый сервер и сказали, что там 3 ТБ диск. По началу я его не увидел, выполнив команду:
df -h
Т.к. утилита df показывает только смонтированные диски. Чтобы увидеть список всех дисков выполните команду:
fdisk -l
Результат команды:
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           2         501      512000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2             502       30720    30944256   8e  Linux LVM
Partition 2 does not end on cylinder boundary.
WARNING: GPT (GUID Partition Table) detected on '/dev/sdb'! The util fdisk doesn't support GPT. Use GNU Parted.
Disk /dev/sdb: 3255.6 GB, 3255585210368 bytes
Из полученной информации было видно, что с нашим диском /dev/sdb что-то не так, т.к. вышло следующее предупреждение:
WARNING: GPT (GUID Partition Table) detected on '/dev/sdb'! 
The util fdisk doesn't support GPT. Use GNU Parted.
В таком виде диск не получится примонтировать. Порыскав в интернете, я нашел долгий, но надежный способ, который мне помог. Для начала нужно заполнить весь диск нулями. 3-х ТБ диск у меня заполнялся нулями за 3 дня. Если вы не можете столько ждать, то вам нужно искать другой более быстрый способ. Команда по заполнению жесткого диска нулями выглядит следующим образом:
dd if=/dev/zero of=/dev/sdb
dd - это программа, предназначенная как для копирования файлов. if указывает файл, из которого производится чтение, а of указывает файл, в который пишутся данные. /dev/zero - специальный файл, представляющий собой бесконечный источник нулей. Вместо /dev/sdb укажите ваш жесткий диск. Терминал, в котором вы запустили команду, нельзя закрывать чтобы не прервать операцию. Причем вам не будет видно хода выполнения. "Как же быть?" - спросите вы. Есть одна хитрая вещь... Вам нужно запустить новый терминал и в нем выполнить команду:
killall -SIGUSR1 dd		
Тем самым вы пошлете команду процессу, запущенного командой dd SIGUSR1 - пользовательский сигнал по которому процесс, запущенный командой dd, выбросит в консоль статистику о ходе заполнения диска нулями в процентах. Также по выведенной скорости вы легко можете рассчитать сколько этот процесс займет времени. После завершения процесса заполнения диска нулями снова выполните команду:
fdisk -l
Чтобы убедиться, что больше не выходи предупреждение:
WARNING: GPT (GUID Partition Table) detected on '/dev/sdb'! 
The util fdisk doesn't support GPT. Use GNU Parted.
Теперь отформатируем диск в файловую систему ext3 (или в любую другую): Внимание!!! Процесс форматирования сразу начнется без подтверждения.
mkfs -t ext3 /dev/sdb
После форматирование выйдет сообщение:
This filesystem will be automatically checked every 24 mounts or  180 days, 
whichever comes first
Дословно это можно перевести как: "Эта файловая система будет автоматически проверяться каждое 24-е монтирование или каждые 180 дней, что наступит раньше". Определимся с директорией монтирования. Давайте примонтируем диск к директории /3t. Создадим директорию:
mkdir /3t
Непосредственно монтирование:
mount /dev/sdb /3t
Все диск доступен! При желании можете выполнить проверку файловой системы: 1) Отмонтировать диск:
umount /dev/sdb
2) Проверка выполняется командой fsck:
fsck /dev/sdb
3) И обратно примонтируем диск:
mount /dev/sdb /3t
Диск проверен и готов к работе!

Неизвестный пасьянс

19 октября выпущена первая версия пасьянса. Представляю вашему вниманию мой любимый пасьянс, который я реализовал под Android. Ссылка в Google Play (Play Market): https://play.google.com/store/apps/details?id=kz.naik.unknownsolitaire Логотип пасьянса: 512x512 Игровое поле выглядит следующим образом: desc В пасьянсе 36 карт. Все карты разбиты на колоды по 3 карты: trio Цель пасьянса: разложить все карты по четырем домам: houses Только верхние карты колод доступны для перемещения: only_top Возможно два вида перемещения карт: 1) Перемещение в дом 2) Перемещение между колодами Перемещение в дом В пустой дом вы можете положить любой доступный для перемещения Туз: add_ace Вслед за Тузом вы должны положить карты такой же масти в следующей последовательности: Король, Дама, Валет, Десятка, Девятка, Восьмерка, Семерка и Шестерка. Перемещение между колодами Перемещение между колодами возможно, если перемещаемая карта одного достоинства с картой, на которую перемещается. Например, мы можем переместить Шестерку только на Шестерку, Даму на Даму и т.д. movement_between Если в колоде уже имеется три карты, то переместить в эту колоду карты нельзя: full Примечание При старте новой игры в случае отсутствия допустимых ходов вы можете взять любой туз из любой колоды, но только один. any_ace Завершенный пасьянс выглядит следующим образом: completed

Быстрое создание папок в формате ГГГГ-ММ-ДД (YYYY-MM-DD)

Если вам часто приходиться создать папки, в названии которых отражена текущая дата в формате ГГГГ-ММ-ДД, то можно автоматизировать создание таких папок. Например, сегодня 24 сентября 2013 года, соответственно папка будет называться 2013-09-24 2013-09-24 Для этого встроим в контекстное меню проводника свой пункт меню, назовем его "YYYY-MM-DD" (название можете придумать свое) контекстное меню Все это делается с помощью файлов реестра с расширением *.reg Всего мы создадим два файла: первый файл будет встраивать пункт меню, а другой удалять этот пункт меню. Готовые файлы можно скачать здесь Ниже в статье идет подробное описание этих файлов и того, как это работает Создайте файл yyyy_mm_dd install.reg Скопируйте в него следующий текст:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\Background\shell\yyyy_mm_dd]
@="YYYY-MM-DD"

[HKEY_CLASSES_ROOT\Directory\Background\shell\yyyy_mm_dd\command]
@="cmd /v:on /c mkdir !date:~-4!-!date:~3,2!-!date:~0,2!"
Windows Registry Editor Version 5.00 - версия редактора реестра. Раздел реестра HKEY_CLASSES_ROOT\Directory\Background\shell отвечает за контекстное меню проводника. Следующий фрагмент создает пункт меню в контекстном меню
[HKEY_CLASSES_ROOT\Directory\Background\shell\yyyy_mm_dd]
@="YYYY-MM-DD"
Вот, что мы увидим, если заглянем в реестр: название Если вложить в созданный раздел yyyy_mm_dd раздел command - это позволит при выборе пункта контекстного меню выполнить команду, которая прописана в параметрах. Следующий фрагмент создает подраздел command и прописывает в нем нашу команду для создания папки:
[HKEY_CLASSES_ROOT\Directory\Background\shell\yyyy_mm_dd\command]
@="cmd /v:on /c mkdir !date:~-4!-!date:~3,2!-!date:~0,2!"
команда Теперь поподробнее о самой команде:
cmd /v:on /c mkdir !date:~-4!-!date:~3,2!-!date:~0,2!
cmd - вызываем интерпретатор командной строки c ключом "/v:on", который разрешает использование переменных среды. Обычно к системным переменным можно обратиться так: %ИМЯ_ПЕРЕМЕННОЙ%, то в данным случае обращение к системной переменной будет в следующем виде: !ИМЯ_ПЕРЕМЕННОЙ! Ключ "/c" - выполнение указанной команды с последующим закрытием командной строки mkdir - команда создания папки, в качестве параметра передается название создаваемой папки. Системная переменная %DATE% возвращает текущую дату. Например, 24.09.2013. На же нужно переобразовать дату в вид 2013-09-24. Для этого нужно выделить части системной переменной и составить требуемое название папки. !date:~-4! - берет из даты "24.09.2013" четыре последних символа, что соответствует году 2013 !date:~3,2! - берет из даты "24.09.2013" два символа начиная с третьей позиции, что соответствует месяцу 09. Причем символы нумеруются с нуля: 24.09.2013 0123456789 date:~0,2 - берет из даты "24.09.2013" два символа начиная с нулевой позиции, что соотвествует дню 24 24.09.2013 0123456789 Далее через дефис выставляем фрагменты в нужной последовательности: !date:~-4!-!date:~3,2!-!date:~0,2! Строит отметить, что если системная переменная %DATE% возвращает дату отличную от формата ДД.ММ.ГГГГ, то нужно будет переделать обработку дат Готовый файл можно скачать здесь Запустите файл yyyy_mm_dd install.reg, выйдет предупреждение, согласитесь с продолжением операции. Как только скрипт отработает, вы можете в любой папке вызвать контекстное меню, в котором будет наш элемент меню "YYYY-MM-DD", по щелчку на котором будет создана новая папка по текущей дате. Удаление пункта из контекстного меню Создайте файл yyyy_mm_dd remove.reg Скопируйте в него следующий текст:
Windows Registry Editor Version 5.00
[-HKEY_CLASSES_ROOT\Directory\Background\shell\yyyy_mm_dd]
[-HKEY_CLASSES_ROOT\Directory\Background\shell\yyyy_mm_dd] - этой командой мы удаляем созданный нами ранее раздел HKEY_CLASSES_ROOT\Directory\Background\shell\yyyy_mm_dd. Дефис (-) перед названием раздела удаляет этот раздел. Готовый файл можно скачать здесь. Запустите файл yyyy_mm_dd remove.reg. Согласившись с выполнением скрипта, будет удален раздел в реестре, отвечающий за наш пункт в контекстном меню.

Создание приложения Android и его запуск на эмуляторе

В предыдущей статье было описана настройка Eclipse для разработки под Android. Теперь создадим приложение и запустим его на эмуляторе. Откройте Eclipse. В меню выберите File -> New -> Other... или нажмите сочетание клавиш Ctrl + N. Откроется окно выбора мастеров. Нам нужен мастер Android Application Project. Выберите его и нажмите Next 1 На следующем шаге нужно указать название приложения, название проекта и пакет. Пакет нужно выбрать таким образом, чтобы сделать ваше приложение уникальным. 2 Также нужно выбрать минимально поддерживаемую версию Android, предпочитаемую версию и версию, с помощью которой будет компилироваться приложение. Можно указать тему приложения. Нажмите Next для перехода к следующему шагу. 3 В этом окне можно ничего не менять, просто нажмите Next. 4 В данном окне можно настроить иконку вашего приложения. Но мы ничего настраивать не будем и идем дальше. Next. 5 Выберите Blank Activity и нажмите Next. 6 Здесь можно настроить название Activity и название макета. Закончим работу с мастером нажатием кнопки Finish.
Создание виртуального устройства Откроем менеджер виртуальных устройств (Android Virtual Device Manager): device manager Нажмите кнопку New... для создания нового виртуального устройства: Android Virtual Device Manager В окне создания виртуального устройства Android обзовите как-нибудь ваше устройство, причем название должно состоять из латинских букв, цифр и символов: ._- Create new AVD Также вам предлагается выбрать экран вашего устройство: screen device Выберите необходимую версию Android. Причем, если вы используете Google API (например, Google Map), нужно выбрать соответствующий пункт с поддержкой Google API: target api Как видно из картинку у меня установлены API только для 8 и 17 версии. Также вы можете настроить дополнительные параметры: фронтальную и заднюю камеры, объем оперативной памяти устройства, внутреннюю память, размер SD-карты и другие параметры. Указав все необходимые параметры, нажмите OK. Добавленное устройство появиться в списке: new device Теперь запустим устройство, выберите его из списка и нажмите кнопку "Start...": start device Появиться окно запроса настроек запуcка, в нем просто нажмите "Launch": launch options Появиться окно эмулятора с кнопками. Дождитесь загрузки Android, это может занять продолжительное время: android loading После загрузки: android desktop Запуск приложения на эмуляторе Окно "Android Virtual Device Manager" можно закрыть. Выберите проект и нажмите кнопку запуска: run application При первом запуске будут предложено как запустить приложение, нужно выбрать запустить как Android Application и нажать кнопку OK: Run As Приложение запущено! Вот так выглядит наше приложение в эмуляторе: application is run