Posts in Category: Разработка

Как повысить уникальность текста? (Антиплагиат)

Так, а теперь реально хорошая новость.

Пожалуй naeplagiat.ru вышел из состояния Бета-версии, но я постараюсь продолжить заниматься самым главным — изучением других способов обхода Антиплагиата. Тот, что эксплуатируют сейчас, конечно, немного сыроват.

Ещё разраз только напомню коротко о главных преимуществах:

  • Пока услуга стоит всего 95 рублей (правда с комиссией Робокассы доходит до 100-105), причём за эти деньги можно обработать 5 различных документов не важно какого размера.
  • Демо-версия раскрывает возможности не менее, чем полностью + в некоторых случаях достаточно только ей и воспользоваться.
  • Пока можно на халяву получить доступ к полной версии за репост со странички ВКонтакте: vk.com/naeplagiat.

Поднятие процентов в системе «Антиплагиат»!

Ура! Запустил сервис по поднятию процентов уникальности в «Антиплагиате»! Теперь обмануть «Антиплагиат» можно за один клик!

С ума сойти, получается с момента, как я начал работать над ним, прошло аж 4 месяца.

naeplagiat.ru

Наеплагиат — наеобойди «Антиплагиат»!

Как обойти «Антиплагиат» (поднятие уникальности docx-файла)

Апдейт!

Не далее как 11 апреля заработал мой сервис для поднятия процентов уникальности Вашего реферата/курсовой/диплома! Над которым я активно работал последние три месяца! Благодарю всех, кто помог мне советами и высказывал пожелания!

Наеплагиат! Подними Уникальность Онлайн!

Многим студентам и преподавателям известна сомнительная по части своей эффективности система «Антиплагиат», которая по заявлению самих её создателей, необходима для проверки текстовых документов на наличие заимствований из общедоступных сетевых источников.

Эту систему часто подвергают критике за её несовершенство.

Своеобразно, что мой реферат, который располагается по одной и той же прямой ссылке (без капчи и без регистрации) уже очень долгое время – более полутора лет, до сих пор не проиндексирован системой и выдаёт более 98% уникальности. То есть любой студент, кто его тупо копирнёт и сдаст получит максимально высокую оценку, 2% же занимает шум в виде распространённых фраз из 2-3 и более слов, типа «компьютеры с разделяемой памятью» и т.д.

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

Казалось бы, как можно заставить программу неверно прочитать текст из вордовского файла, прекрасно открывающегося и читающегося в самом ворде?

Сначала скажу, как я вообще занялся этой проблемой. Моя подруга обратилась ко мне с необычными вопросами, связанными с прохождением файла на плагиат. Например, она спрашивала, почему иногда если удалить абзац, а потом набрать его же слово в слово вручную, уникальность текста повысится? Действительно очень странно. В чём же дело? Я так и не придумал, а она решила заказать платную услугу и заплатив всего около 400 рублей получила файл, который вместо 37% уникальности, стал выдавать 82%. Файл совсем не поменялся, его можно было даже редактировать – он продолжал сохранять свои антиплагиатские свойства.

Первое на что я обратил внимание – это вес файла. Он весил значительно больше, где-то в 3 раза. При этом в нём не было картинок и прочих не текстовых элементов. Я пересохранил файл в xml и открыл его. Открылась интересная картина, очень многие слова были разорваны. Тогда я ещё не знал, как устроена вордовская xml-разметка (так называемый WordprocessingML), но я сразу понял, что всё дело может быть только в этом и что «Антиплагиат» воспринимает текст как абракадабру (по этим кусочкам).

Я создал пустой файл, написал в нём короткое предложение, а затем вручную повторил разрывание слов в разметке. Однако пересохранив файл снова в docx и затем снова в xml, я увидел, что всё сбилось и слова снова объединились в предложение внутри одного тега.

На этом мой интерес пропал, однако прошло несколько месяцев и человек снова поинтересовался, не нашёл ли я способ борьбы с «Антиплагиатом»? Наступили последние деньки декабря – время приятной расслабухи на работе. Я начал возиться с xml, пытаясь понять причину, почему же мой разорванный xml сбивается вордом, а фирменный – нет. К моему счастью в разметке почти не было чего-то, что могло рассеять моё внимание – всё дело было в атрибуте rsidR, который отвечает за идентификацию правки (как я понял). Он должен был непременно изменяться от кусочка текста к кусочку. Иначе ворд считал, что нет смысла в разорванности кусочков и их надо обязательно объединить. В итоге моей целью стало написание скрипта, который бы (в общих чертах) из такого:

<w:p> 
    <w:r> 
        <w:t>Атиплагиат гавно.</w:t> 
    </w:r> 
</w:p>

делал бы такое:

<w:p> 
    <w:r w:rsidR="00947664"> 
        <w:t>Атип</w:t> 
    </w:r> 
    <w:r w:rsidR="00947665"> 
        <w:t>лагиат гав</w:t> 
    </w:r>
    <w:r w:rsidR="00947664"> 
        <w:t>но.</w:t> 
    </w:r>
</w:p>

В связи с чем система бы получала бы текст «Антип лагиат гав но»

И я взялся за работу, выбор конечно же пал на PHP, т.к. это возможность веб-реализации, а значит 100% доступного, если что, всем приложения.

Результатом моей работы стал вот такой скрипт, не требующий никаких ни библиотек, ни БД, ничего.

Выложенный файл – набросок, он только реализует разрывание, чтобы поднимать уникальность не на максимум, а на выбранный процент, нужно добавить пару строчек кода.

Придя домой, я зарегился на «Антиплагиате» и решил проверить, как же хорошо он в итоге работает. Удивлению не было предела – процент уникальности не поменялся. Тогда я решил собственноручно проверить тот самый гарантированно 82% файл, и о, нет – он также выдавал лишь 37%. Так я выяснил, что разработчики «Антиплагиата» пофиксили эту дыру размером с кулак. Видимо они проходятся по всем <w:r> (во, хакеры), в терминологии ворда это «run», типа как <span> в html, т.е. текстовый элемент типа display: inline, и тупо удаляют у всех атрибут w:rsidR.

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

Поскольку человек, благодаря которому я увлёкся этой темой, просил меня не раскрывать существующих методов борьбы с этой несовершенной системой, я не буду писать об этом.

Хотел бы только поблагодарить замечательного сотрудника корпорации Mircrosoft Брайана Джонса, который в своих заметках очень понятно описал некоторые вещи, проясняющие устройство WordprocessingML.

А если кому-то нужно отхакать какой-то плагиатный реферат или диплом – обращайтесь

Шифрование с помощью аффинной системы подстановок Цезаря (JavaScript)

Только на первом курсе магистратуры я первый раз за всё время решил сдать лабу на жс.

Это была первая лаба по достаточно интересному предмету про шифрование. Я бы с радостью сделал и другие лабы на жс, но переделывать арифметику из оригинальных найденных кодов было тяжело. Вся проблема была в различии арифметики Java и JS, которое давало о себе знать, когда дело касалось больших целых чисел.

Но поскольку в элементарном шифровании Цезаря больших целых чисел нет, а алгоритм предельно прост, было очень нетрудно, и даже интересно сделать всё на скрипте.

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

Думаю, что студентам также, возможно, окажется полезным задание и отчёт.

Работа с кварталами (время) в JavaScript

Сегодня моему приятелю было нужно сделать на работе инструмент, частью функционала которого была работа с кварталами. А именно, необходимо было узнавать номер квартала для даты, а также находить его границы. У меня было свободное время и я решил тоже попробовать решить такую задачку.

Тут же нагуглили этот полезный ответ Math.floor((date.getMonth() + 3) / 3), однако оставалось находить границы квартала.

В то время, как я тут же принялся быдлокодить такую функцию:

function getQuarterBounds(date) {
    date = date || new Date();

    var q = Math.floor((date.getMonth() + 3) / 3);
    var year = date.getFullYear();
    var quarters = {
        1: {
            start: '01-01',
            end: '03-31'
        }, 2: {
            start: '04-01',
            end: '06-30'
        }, 3: {
            start: '07-01',
            end: '09-30'
        }, 4: {
            start: '10-01',
            end: '12-31'
        }
    };

    return [
        new Date(year + '-' + quarters[q].start),
        new Date(year + '-' + quarters[q].end)
    ];
}

Мой приятель обратил внимание, что функция setMonth() вторым аргументом имеет день, который в случае, если равен 0, ставит последний день предыдущего месяца, а при -1 и меньших значений начинает мотать дальше.

В нашем случае этот функционал оказался как раз очень удобен:

function getQuarterBounds(date) {
    date = date || new Date();

    return [
        new Date(new Date().setMonth(
            date.getMonth() - date.getMonth() % 3, 1)),
        new Date(new Date().setMonth(
            date.getMonth() + 3 - date.getMonth() % 3, 0))
    ];
}

Да уж, иногда бывает, что вспоминаешь неутешительное «RTFM»

Тестовое задание Яндекса (Trip Sorter)

При приёме программистов на работу, кандидатам любят давать тестовые задания. Чаще всего их можно получить от убогих кадровых агентств, тогда к ним лучше не приступать, либо от нормальных компаний после собеседования, тогда стоит подумать, нужно ли тратить на них время или не стоит, в зависимости от того, какое впечатление произвела компания. А можно получить задание на проверку скилов и от очень брендовых с точки зрения HR компаний, коей в области ИТ у нас в стране и является Yandex, занимая, возможно, самое первое место.

Сразу скажу, моё решение задачи не понравилось программистам из Яндекса, а как я понял со слов рекрутёра, из было аж трое, так что задание я запорол.

Как показано в одном комиксе из серии “What I really do”, суть работы программиста заключается в наборе в строке поиска слов “how to Java”. В каждой шутке есть доля правды, и едва приступив к заданию, я решил посмотреть, не делал ли его кто-нибудь до меня. Сначала я пробил слова из задания и ничего не обнаружил, а затем попробовал вбить само название файла, которое было на английском. Тогда я наткнулся на блог какого-то разработчика, кажется он был из Испании. Человек писал в своём блоге о том, что в компании ему предложили следующее тестовое, и что ему обидно, что его не взяли на работу туда.

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

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

Возможно однажды кто-нибудь будет ещё раз гуглить это тестовое, так что вот.

Буду рад, если кто-нибудь скажет, что в решении есть ошибки.

Simple Combobox — jQuery плагин

Этой весной впервые поработал немного фрилансером, мне нужно было сделать форму, в которой было несколько элементов с автокомплитом. Элементы зависели друг от друга (речь шла о заполнении формы адреса по КЛАДР). Я решил, что будет проще набросать собственный механизм для автокомплита и поначалу оформил это как набор лисенеров, управляя этими компонентами и меняя их данные вручную. Но затем, доделав работу до конца, подумал, что было бы здорово сделать такой компонент jQuery плагином. В итоге поулчилась вот такая штука.

Бегущая строка (табло) на JavaScript

Бывает, что на работе выдаётся свободное время. Особенно приятно это, когда под самый Новый Год, в последние деньки, работа, после самого активного в году времени вдруг резко заканчивается. Не перестаю не замечать за собой, что кодить для себя практически всегда интересней, чем что-то по работе. Наверно потому что по своей инициативе выбираешь как раз то, что интересно больше всего.

Как-то раз, сидя в вагоне «Русича» и глядя на табло, я подумал, а как интересно кодят его сообщения и как вообще оно работает в плане отображения текста в виде точек и, самое главное, его анимации.

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

Было это кстати ещё давно, уже почти год назад, сейчас я бы возможно оформил код по-другому, однако всё равно скрипт вышел вполне рабочим и достаточно интересным.

Из плюшек я добавил возможность захватывания текущего текста на табло. Он автоматически обрезается, то есть триммится, это очень удобно для кодирования символов – вы рисуете букву, после чего нажимаете кнопочку и тут же получаете её код, которым можно пополнить алфавит. А ещё позаботился о такой простой фиче, как сохранении текущего текста в юрл странички. Кроме этого, по нажатию на странице на стрелочки вверх и вниз с зажатым контролом, бегущая строка меняет скорость. Над ней также выводятся символы, которых нет в подключённом алфавите.

Я бы безумно хотел, чтобы пиксели анимировались плавно, а не меняли свою opacity в миг, но в таком случае во всех браузерах начинаются очень неприятные тормоза. Честно говоря, я впервые задумался, что это так плохо, что я не знаю экшенскрипт, который, как мне кажется, работал бы безупречно быстро в данной задаче. Хотя вполне возможно, что решение этой задачи с помощью жс на канвасе было бы таким же быстрым.

Доведя работу до точки, а случилось это только днём 31 декабря, я отправился на празднование Нового Года к другу. Новый Год мы встретили чудесно в замечательной компании, а на следующий день я отправил ссылку на страничку близким друзьям.

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

Страничка, zip, GitHub.

Про table с `display: block` и `overflow-y: auto`

Недавно была у нас страничка, там появлалась очень широкая таблица, которая разрывала страницу, т.е. заставляла появиться горизонтальный скролл на body. Мы решили эту проблему добавлением стиля на таблицу, а именно { display: block; overflow-y: auto; max-width: 10px /* любая маленькая величина */ }.

Но как известно, таблицы не предназначены для того, чтобы на них вешался display: block, поэтому несмотря на многочисленные попытки сделать что-то универсальное, у других, более узких таблиц, возникли проблемы.

Мы решили, что надо определять, рвёт ли таблица страницу, или не рвёт.

Тут же нашли решение – вот такой компактный jquery-плагин здесь:

$.fn.hasOverflow = function() { 
    var $this = $(this); 
    var $children = $this.find('*'); 
    var len = $children.length; 
 
    if (len) { 
        var maxWidth = 0; 
        var maxHeight = 0 
        $children.map(function() { 
            maxWidth = Math.max(maxWidth, $(this).outerWidth(true)); 
            maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); 
        }); 
 
        return maxWidth > $this.width() || maxHeight > $this.height(); 
    } 
 
    return false; 
};

Мы подправили его так, чтобы рассматривалась только ширина и использовали его следующим образом: $('body').hasOverflow().

Однако в некоторых случаях он не срабатывал (может быть ещё что-то другое изменилось на странице) и кроме этого не очень приятно, что выборка элементов может быть чересчур громоздкой – это может даже влиять на тормознутость страницы. Но на следующий день мы начали думать над этим заново и очень скоро пришли к очень простому методу проверки:

$(window).width() < $('body')[0].scrollWidth

Пока исправно работает! Утро вечера мудренее

Поведение `for (var i in arr)` в IE8 после расширения Array.prototype

Недавно решил посмотреть, как дела у моего jQuery плагина в IE8. Я думаю, предсказать что было дальше не сложнее, чем предугадать, чем закончится классическая голливудская мелодрама – в скрипте обнаружились ошибки.

Из-за убогости консоли я долго думал в чём дело и столкнулся с необычным явлением. Как известно, IE8, как и все другие десктопные браузеры от Microsoft с момента своего появления является сильно устаревшим браузером. В частности, в нём нет ряда методов из Array.prototype, таких как весьма удобный и относительно часто используемый indexOf(obj). Естественно я знал это и позаботился, добавив к проекту небольшой скрипт missed.js, который кочует у меня из проекта в проект, разрешая проблему недостающего функционала в IE8. Этот скрипт – классическое решение, он содержит ряд объявлений вида:

if (!Array.prototype.indexOf) { 
    Array.prototype.indexOf = function(...) {...} 
}

Не знаю, почему я впервые наткнулся на ошибку только недавно, но в общем это был первый раз, когда я увидел, как после этого будет использоваться код вида for (var i in arr), в случае, когда arr – массив.

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

Обсудив это с коллегой я пришёл к выводу, что лучше для массивов всегда использовать код вида for (var i = 0; i < arr.length; i++).