Wednesday, March 28, 2007

Определение длины mp3 файла (удаленного)

Под длиной в данном случае подразумевается продожительность.

С самого начала разработки наступил на очень интересные "грабли".
Изначально хотелось в выдаче указывать продолжительность найденых mp3 файлов(в купе с физической длиной и id3 информацией) для того, чтобы пользователи могли определить - соответсвует результат запросу или нет. Естественно - качать каждый файл желания никакого не было и нет.
И тут началось самое интересное.

Немного о формате.
Формат mp3 имеет фреймовую структуру(это от того, что файл кодируется не сразу и целиком, а делится сначала на определенного размера блоки(фреймы) и эти блоки кодируются отдельно). И вот таких фреймов может быть не один и не два.

Первое, что бросилось в глаза в формате заголовка фрейма - отсутсвие информации о длине. Второй неприятный момент - это то, что битрейт может быть разным (т.н. VBR)для различных фреймов.

Что ж, длинну композиции, не имея в своем распоряжении всего файла точно определить неудастся. А жаль.

Конечно, можно было пойти другим путем - если битрейт постоянный и известен размер файла можно _примерно_ определить продолжительность(что не есть хорошо, но лучше, чем ничего). Т.е. этот вариант отпадает также (т.к. все фреймы без файла не получим, битрейты соответсвенно - тоже не знаем).

Но и на этом неприятности не кончились.
Как известно - существует две версии ID3 Tag'ов - первая и вторая. Так вот, первая версия распологается в конце файла(последние 128 байт, если не ошибаюсь), а вторая - в начале. Т.е. для получения ID3v1 опять же необходимо скачивать полностью весь файл.

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

PS: возможно кто-то cможет дать совет, как бороться с вышеописанными проблемами ?

Sunday, March 25, 2007

Поиск mp3 файлов доступных для скачивания

Начинаю работу над новым проектом - сервис, предоставляющий
пользователям возможность поиска mp3 файлов, доступных для скачивания (конечная ссылка - сам mp3 файл).

Сервис будет написан на Perl.
Первоначально бля поиска будет использоваться google search engine.
В дополнитение предполагается предоставление технической информации о mp3 файле (продолжительность, битрейт, возможно что-то еще), возможность прослушать файл.

Это то, что необходимо сделать в первую очередь, в дальнейшем список сервисов будет расти.

Сейчас вплотную занимаюсь составлением списка сервисов, необходимых библиотек, подбором домена - т.е. организаторской работой.

Если у кого-то есть какие-либо пожелания (что бы Вы хотели увидеть на данном сервисе) - welcome to comments.

Diceware Passphrase

Источник

Diceware Passphrase - это предельно простой алгоритм генерации
паролей. Насколько длинных - настолько простых к запоминанию.
Алгоритм строится на принципе "кидания 5 игральных костей N раз" и
определнию комбинаций из цифр с последующим сопоставлением этих цифр определенным словам.
По ссылке, указаной выше можно скачать такой файл соответствия.
Выглядит он следующим образом:
11126 abase
11131 abash
11132 abate

Принцип следующий:
Кидаем 5 костей первый раз, записываем получившееся 5-значное число.
Кидаем второй раз - опять записываем.
И так подряд столько раз, сколько необходимо.
Затем по файлу определяем слова соответствующие цифрам и производим конкатенацию.
В общем-то - это и есть весь алгоритм. Даже алгоритмом можно назвать
с достаточно сильной натяжкой.
Код (исключительно ознакомительный, как пример):

public class Diceware {

private SecureRandom secureRandom = new SecureRandom();
private Map wordlist = new HashMap();

public Diceware(String wordslistPath) throws IOException {
File file = new File(wordslistPath);
InputStream is = new FileInputStream(file);
Reader reader = new InputStreamReader(is);
BufferedReader bufferedReader = new BufferedReader(reader);

String pair[];
String line;
while ((line = bufferedReader.readLine()) != null) {
pair = line.split(",");
wordlist.put(pair[0], pair[1]);
}
bufferedReader.close();
reader.close();
is.close();
}

public String getPassphrase(int rolls) {
String passphrase = "";
String tmp = "";
for (int i = 0; i < rolls; i++) {
for (int j = 0; j < 5; j++) {
tmp += secureRandom.nextInt(6) + 1;
}
passphrase += wordlist.get(tmp);
tmp = "";
}
return passphrase;
}
}

PS: вопрос на засыпку: как можно лаконично перевести на русский слово passphrase в данном контексте:
"A passphrase is a bunch of words and characters that you type in to your computer to let it know for sure that the person typing is you. Most newer security programs allow you to enter a passphrase instead of just a short password for added protection against attackers."

Friday, March 23, 2007

Аудит изменения данных в таблицах

Аудит изменения данных в таблицах

Встала задача производить аудит изменения данных в таблицах.
Было необходимо сохранить:
  • Название таблицы
  • Столбец
  • Старое значение в таблице
  • Новое значение в таблице
  • Название столбца, являющего Primary Key
  • Значение столбца, являющего Primary Key
  • ID пользователя, внесшего изменения

Первое, что пришло в голову - это написать триггер, который бы
этим занимался.
Все оказалось не столь тривиально, как на первый взгляд.

Перво наперво задача была поделена на подзадачи.
  1. Как получить имя изменяемой таблицы.
  2. Как получить изменяемый столбец.
  3. Как получить старое значение.
  4. Как получить новой значение.
  5. Как узнать primary key этой таблицы.
  6. Как узнать значение primary key этой таблицы.
  7. Как передать ID пользователя.

Поспрашивав на форумах и почитав документацию ответы были найдены:

  1. Триггер создается на каждую таблицу, имя известно заранее.
  2. Воспользоваться update(), COLUMNS_UPDATED ( )
  3. Использовать таблицы inseted, updated
  4. Аналогично 3.
  5. SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    SELECT * FROM sys.objects WHERE type = 'pk'
  6. Аналогично пункту 3

Остался открытым вопрос - как передать ID пользователя в триггер.
Можно использовать что-то вроде tmp view, но я в этом не уверен.
В обще - процесс написания запущен, посмотрим, что из этого выйдет.

Если кто-то что-то знает по этой теме и может помочь - милости просим в comments.

Thursday, March 15, 2007

Запрет на UPDATE/DELETE/INSERT посредством триггера

Иногда(на практике - в очень редких случаях) может понадобиться
запретить обновление, удоление или добавление данных в таблицу
посредством триггера.
На первый взгляд кому-то задача может показаться сложной, но на
самом деле все крайне тривиально.

Пример такого триггера (при попытке UPDATE возникает EXCEPTION):


CREATE OR REPLACE TRIGGER Trigger_Name
BEFORE UPDATE
ON Some_Table
BEGIN
RAISE_APPLICATION_ERROR(-20001, 'Cant update data');;
END;


Никакой магии - все предельно просто :)

Wednesday, March 14, 2007

Регистрация доменного имени

Уж очень мне понравился регистратор webst.ru
1. Очень вкусный ценник:

COM — 6,99 $
NET — 6,99 $
ORG — 1,89 $
INFO — 1,85 $
BIZ — 6,99 $


2. Работают быстро (на своем опыте говорю)
3. Саппорт тоже отвечал на все вопросы крайне оперативно.
В общем, для меня это было главное - соотношение цена/оперативность саппорта/время регистрации.

Рекомендую (webst.ru).