mini-notes-issue-5/

Основные темы пятого выпуска: FreeBSD, Haskell, парное программирование, алгоритм шифрования lameCrypt на Perl и отрывки кода на PHP, имеющие отношение к поисковой оптимизации. Предыдущие выпуски: первый , второй , третий и четвертый .

1. Один интересный прием на Haskell

Этот отрывок кода я подглядел в архиве почтовой рассылки haskell-cafe :

{-# LANGUAGE FlexibleInstances, UndecidableInstances,
ScopedTypeVariables, OverlappingInstances #-}

import System . Random

class ( Bounded a , Enum a ) => BoundedEnum a
instance ( Bounded a , Enum a ) => BoundedEnum a
instance BoundedEnum a => Random a where
random gen = randomR ( minBound :: a , maxBound :: a ) gen
randomR ( f , t ) gen =
( toEnum r :: a , nextGen )
where
( rnd , nextGen ) = next gen
r = fromEnum f + ( rnd ` mod ` length [ f .. t ] )

Он позволяет говорить…

r <- randomIO :: Anything

…для любого типа Anything, являющегося экземпляром классов Enum и Bounded. Это позволяет не писать множество функций genRandomTypeN для каждого типа TypeN. В некоторых программах такой прием может быть очень полезен.

2. Удаленное парное программирование в screen

Есть несколько способов организовать удаленное парное программирование . Можно использовать для этого VNC или вашу IDE (такая возможность точно есть в Visual Studio, а также существует несколько плагинов для Eclipse). Но если вы и ваши коллеги предпочитают использовать VIM , то для удаленного парного программирования вы можете использовать утилиту screen.

Допустим, программисты с никами afiskon и eax решили программировать в паре с использованием screen. Для этого afiskon заходит на unix-сервер, где также имеет учетную запись eax, и говорит:

screen -R pairprog
:multiuser on
:acladd eax

Затем eax заходит на тот же сервер и выполняет команду:

screen -x afiskon / pairprog

Вот и все! См также man screen, особенно его часть про управление доступом (команда aclchg).

3. Оптимизация сайта под запросы с опечатками

Эту идею я подглядел на Blogerator.ru (см конец статьи) . Идея состоит в том, чтобы находить в статье словосочетания на латинице и дописывать в конце эти словосочетания, набранные в русской раскладке. Например, если в статье встречаются слова «perl», «freebsd» и «haskell», то в конце статьи должно быть написано «зукд», «акууиыв» и «рфылудд». Это дело несложно автоматизировать:

// находим все словосочетания на английском
$content = preg_replace ( ‘/<[^>]+?>/’ , » , get_the_content ( ) ) ;
preg_match_all ( ‘/s+([a-z][a-z_- ]{3,}[a-z])s+/i’ ,
$content , $match ) ;

// приводим их к нижнему регистру и удаляем повторы
$keywords = array_map ( «strtolower» , $match [ 1 ] ) ;
$keywords = array_slice ( array_unique ( $keywords ) , 0 , 10 ) ;

// получаем опечатки
$replaceFrom = «abcdefghijklmnopqrstuvwxyz» ;
$replaceTo = mb_convert_encoding ( «фисвуапршолдьтщзйкыегмцчня» ,
«CP-1251» , «UTF-8» ) ;
$funcCode =
‘return mb_convert_encoding(‘ .
‘strtr($x, «‘ . $replaceFrom . ‘», «‘ . $replaceTo . ‘»), ‘ .
‘»UTF-8″, «CP-1251»);’ ;
$rusKeywords = array_map ( create_function ( ‘$x’ , $funcCode ) , $keywords ) ;

// объединяем
$keywords = implode ( «, » , array_merge ( $keywords , $rusKeywords ) ) ;

Я проверял, трафик с поисковых систем действительно увеличивается. Однако следует отметить, что Яндекс обещал жестоко наказывать за переоптимизацию сайтов , так что подумайте перед тем, как пользоваться это «темой».

4. BlogSpot + ZoneEdit

Если вы хотите создать сайт, но деньги есть только на доменное имя (от 100 рублей в год), воспользуйтесь следующей последовательностью шагов:

  1. Создаем блог на blogspot.com ;
  2. Регистрируемся на zoneedit.com ;
  3. Регистрируем доменное имя;
  4. Присваиваем доменному имени DNS’ы от ZoneEdit (например, ns5.zoneedit.com и ns7.zoneedit.com);
  5. Через ZoneEdit ставим в соответствие домену IP-адреса блогспота (на данный момент это 216.239.38.21, 216.239.32.21, 216.239.34.21 и 216.239.36.21);
  6. Проверяем настройки с помощью whois и dig (помним, что на обновление зоны нужны сутки);
  7. Если все ОК, прописываем в свойствах блога доменное имя;
  8. Получили бесплатный хостинг и бесплатные DNS сервера. Оплате подлежит только продление домена раз в год;

О том, как заработать на таком сайте, вы можете узнать из заметки Схема заработка в GoGetLinks, которая работает . Из недостатков приема — (1) зависимость от BlogSpot и ZoneEdit, (2) о добавлении сайта в SAPE придется забыть.

5. OpenDNS и GoogleDNS

OpenDNS:

nameserver 208.67.222.222
nameserver 208.67.220.220

GoogleDNS:

nameserver 8.8.8.8
nameserver 8.8.4.4

Запомнить наизусть!

6. Определение объема свободной памяти во FreeBSD

Во FreeBSD для определения суммарного объема свободной оперативной памяти с помощью, скажем, утилиты top требуется произвести дополнительные вычисления в уме. Я лично все время забываю, что с чем нужно складывать, поэтому предпочитаю использовать утилиту freecolor (легко ставится из пакеджей или портов ).

Утилита freecolor

На приведенном скриншоте freecolor говорит, что 34% оперативной памяти (703 Мб) свободно. Все просто и понятно.

7. Проверка IP на наличие в спам-списках

Перепост отсюда :

www.spamhaus.org/query/bl?ip=1.1.1.1
www.senderbase.org/senderbase_queries/detailip?search_string=1.1.1.1
support.clean-mx.de/clean-mx/publog?ip=1.1.1.1
www.spamcop.net/w3m?action=checkblock&ip=1.1.1.1

Еще больше таких сервисов можно найти здесь .

8. Как не нужно шифровать данные

Некоторые задачи требуют быстрого решения . Если у вас нет времени на установку CPAN-модуля Crypt::Rijndael (код требуется развернуть на сотне серверов, нужен таск на админов, …), можете воспользоваться алгоритмом вроде этого:

#!/usr/bin/env perl

use strict ;
use Digest :: MD5 qw/md5_hex/ ;

#use String::CRC32 qw/crc32/;
#sub md5_hex { sprintf(«%08x», crc32(@_)) }

sub lameCrypt {
my ( $str , $key , $decrypt ) = @_ ;
return » unless length ( $str ) ;

unless ( $decrypt ) {
my $iv = » ;
while ( length ( $iv ) < 16 ) {
my $t ; $t .= rand ( ) for ( 0 .. 7 ) ;
$iv .= md5_hex ( $iv . time ( ) . $$ . $t ) ;
}
$str = substr ( $iv , 0 , 16 ) . unpack ( «h*» , $str ) ;
}

my $l_len = int ( length ( $str ) / 2 ) ;
my $r_len = length ( $str ) $l_len ;
my $splitRe = qr/^(.{$l_len})(.{$r_len})$/o ;

my ( $rounds , $left , $right ) = ( 32 , undef , undef ) ;
for my $i ( 1 .. $rounds ) {
( $left , $right ) = $str =~ $splitRe ;
my $f = » ;
while ( length ( $f ) < $r_len ) {
$f .= md5_hex (
$f . $left . ( $decrypt ? $rounds $i + 1 : $i ) . $key
) ;
}
my $j = 0 ;
$right = join » , map {
sprintf ( «%x» , hex ( $_ ) ^ hex ( substr ( $f , $j ++, 1 ) ) )
} split ( //, $right ) ;
$str = $right . $left ;
}

$str = $left . $right ;
return $str unless ( $decrypt ) ;
return pack ( «h*» , substr ( $str , 16 , length ( $str ) 16 ) ) ;
}

my $str = «secret message» ;
my $key = «aaa123» ;
my $enc = lameCrypt ( $str , $key , 0 ) ;
my $dec = lameCrypt ( $enc , $key , 1 ) ;
print «str = $str n enc = $enc n dec = $dec n » ;

Алгоритм представляет собой сеть Фейстеля , причем размер блока равен длине (де)шефруемой строки. Если в строке нечетное количество байт, то при разбиении блока левая половина делается на один байт меньше правой. Функция F основана на алгоритме MD5.

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

9. FreeBSD — установка модулей Python из PyPI

Для установки модулей Python под FreeBSD оказалось очень удобно использовать утилиту pip.

pkg_add -r py27-pip # устанавливаем pip
pip search wordpress # поиск модулей
pip install pil # установка модуля
pip uninstall pil # удаление модуля
pip freeze # список установленных модулей

См также http://pypi.python.org/pypi .

10. Статистика поисковых запросов своими руками

В каком-нибудь footer.php дописываем:

<?php
$ref = $_SERVER [ ‘HTTP_REFERER’ ] ;
if ( preg_match ( ‘/^http://(www.)?(yandex|google)/’ , $ref ) ) {
$fid = fopen ( «/path/to/ref.txt» , «a» ) ;
fwrite ( $fid , date ( «Y-m-d» ) . » t » . $_SERVER [ ‘REQUEST_URI’ ] . » t $ref n » ) ;
fclose ( $fid ) ;
}
?>

Ждем пару недель, после чего скармливаем файл ref.txt следующему скрипту:

#!/usr/bin/perl

# ref.txt parser v 0.1
# (c) Alexandr A Alexeev 2012 | http://remontka.com/

use strict ;
use warnings ;
use utf8 ;

use URI :: Escape ;

my $gre = qr «www . google . [^/]+/.*?[ # ? & ]{1}(?:as_)?q=([^ & ]*)» i ;
my $yre = qr «yandex . [^/]+/.*?[ ? & ]{1}(?:text|query)=([^ & ]*)» i ;
my $ire = qr «www . google . [^/]+/(notebook|reader|imgres|webhp)» i ;

my % stat ; # {url t query} = cnt
my $fails = 0 ;
while ( my $line = <> ) {
chomp ( $line ) ;
my ( $date , $url , $ref ) = split /t/ , $line ;
my $query ;
if ( $ref =~ $gre ) {
$query = $1 ;
} elsif ( $ref =~ $yre ) {
$query = $1 ;
} else {
next if ( $ref =~ m «^http://[^/]+/?$» i ) ;
next if ( $ref =~ m «www . google . [^/]+/search$» i ) ;
next if ( $ref =~ m «doubleclick . net/pagead/» i ) ;
next if ( $ref =~ $ire ) ;
warn «Failed to parse: $ref n » ;
$fails ++;
}
next unless ( $query ) ;
$query = uri_unescape ( $query ) ;
$query =~ s/+/ /g ;
$query =~ s/s+/ /g ;
$query = lc ( $query ) ;
$stat { «$url t $query» } ++;
}

if ( $fails ) {
warn «Total fails: $fails n ———— n » ;
}

for my $url_query ( sort { $stat { $b } <=> $stat { $a } } keys % stat ) {
my ( $url , $query ) = split /t/ , $url_query ;
my $cnt = $stat { $url_query } ;
printf «%09d t %s t %s n » , $cnt , $url , $query ;
}

Затем можно прогнать полученный список запросов через wordstat.yandex.ru и закупить внешних ссылок или провести внутреннюю оптимизацию сайта (перелинковка, заголовки и тп).

Собственно, это все. Как обычно, я буду несказанно рад вашим комментариям и вопросам.

Дополнение: Мини заметки — выпуск 6

EnglishRussianUkrainian