2 maja 2015

[C++Now!] Michael Caisse: Introduction to Modern C++ Techniques

Dwa ciekawe wykłady, na temat nowoczesnych technik stosowanych w C++ (choć z 2012 roku). To co mnie zainteresowało (a szczególnie ostatni punkt):
  • Traits
  • Policy Classes
  • CRTP (Curiously Recurring Template Pattern)
  • SFINAE (Substitution Failure is Not An Error)
  • Units - jak radzić sobie z jednostkami fizycznymi



11 kwietnia 2015

[C++11] Aliasy na szablony z wykorzystaniem using

W nowym standardzie using zyskał nowe właściwości pozwalające na tworzenie aliasów do typów. Parametrem takiego aliasu, może być także stała znana w czasie kompilacji (np. rozmiar dla std::array). Nie ma możliwości tworzenia specjalizacji.
#include <iostream>
#include <map>

template <typename T>
using CourseGrade = std::map<std::string, T>;

int main()
{
    CourseGrade<double> mathCourse;

    mathCourse["Jhon"] = 3.5;
    return 0;
}

4 kwietnia 2015

Ataki na z/OS

Czytając artykuł na ZaufanejTrzciejStronie,
przypomniał mi się wykład na temat ataków na platformę z/OS z DEF CON 2014.



Pieniądze w bankach, znów nie wyglądają na takie bezpieczne...

[PowerShell] Wyszukiwanie plików ukrytych

Gdyby zaszła potrzeba znalezienia ukrytego pliku, konfigurującego wirusa rządowego:
Wydaj mi się, że PowerShell jest całkiem potężnym narzędziem, ale gdy chce rozwiązać nim jakiś problem zawsze napotykam na jego ograniczenia. Właściwe wyszukiwanie
  • -Force - zwraca wszystkie pliki w folderze, nawet te ukryte
  • -ErrorAction SilentlyContinue - niektóre zasoby jak np. "c:\Users\beru\Documents\My Music" występują jako jakaś windowsowa forma dowiązania (junction). Ta opcja ukrywa las błędów, który jest generowany przez nieudane próby wejścia. Plik z "My Music" są umieszczone w "c:\Users\beru\Music" i ten folder zostanie przeszukany
# Pomoc
Get-Help Get-ChildItem
Get-Help Get-ChildItem -Detailed

# Sprawdzenie atrybuty pliku
(Get-ItemProperty .\Music\f14.conf).attributes.ToString() -match "Hidden"

# Wyszukiwanie
Get-ChildItem . -Force -Recurse -ErrorAction SilentlyContinue | Where-Object {$_.mode -match "h" -and $_.name -eq "f14.conf"}

28 lutego 2015

[boost] Sprawdzenie typu za pomocą typeindex

Od wersji 1.56 boost, posiada fajną bibliotekę, dostarczająca informacje o typie zmiennej (boost_typeindex). Podobno radzi sobie lepiej, niż mechanizmy typeid() albo std::type_index (C++11). Z pewnością wyniki są bardziej czytelne dla człowieka.

W Ubuntu 14.10 dostępny jest tylko boost w wersji 1.55, więc trzeba ściągnąć źródła samodzielnie:
wget -c http://sourceforge.net/projects/boost/files/boost/1.57.0/boost_1_57_0.tar.gz/download
mv download boost_1_57.tar.gz
tar -zxv boost_1_57.tar.gz
Podczas kompilacji trzeba jeszcze wskazać gdzie są nasze pliki nagłówkowe:
g++ -std=c++14 -I/home/beru/boost_1_57_0/ main.cpp
A teraz testowanie. auto w trakcie dedukcji typu usuwa modyfikatory const i volatile.
#include <iostream>
#include <vector>
#include <boost/type_index.hpp>

using namespace std;

int main()
{
    const vector<int> val1;
    auto  a = val1;
    auto& b = val1;

    int val2 = 44;
    const int* p = &val2;
    auto c = p;

    cout << "For a: " << boost::typeindex::type_id_with_cvr<decltype(a)>().pretty_name() << endl;
    cout << "For b: " << boost::typeindex::type_id_with_cvr<decltype(b)>().pretty_name() << endl;
    cout << "For c: " << boost::typeindex::type_id_with_cvr<decltype(c)>().pretty_name() << endl;

    return 0;
}
Wynik:
For a: std::vector<int, std::allocator<int> >
For b: std::vector<int, std::allocator<int> > const&
For c: int const*

18 lutego 2015

wget - utworzenie sesji i archiwizacja strony

Rozwiązanie problemu archiwizacji strony, do której konieczne jest logowanie. Po zalogowaniu tworzona jest sesja, którą można wykorzystać do ściągnięcia zawartości strony:
wget --save-cookies cookies.txt \    # zapisuje ciasteczko
     --keep-session-cookies \        # ciasteczka sesji normalnie nie są zapisywane, ta opcja to wymusza
     --post-data 'user=Alice&pass=123' \ # logowanie na stronie (metoda POST)
     http://example.com

wget --recursive \                   # przeszukaj stronę rekursywnie
     --cookies=on \                  # man nie opisuje, wget nie odrzuca, niektóre przykłady podają (?)
     --load-cookies cookies.txt \    # ładuje wcześniej zapisane cookie
     --keep-session-cookies \        # nadal utrzymuje cookie sesji 
     --no-clobber \                  # nie nadpisuj już istniejących plików
     --page-requisites \             # ściągnij wszystkie pliki (pliki dźwiękowe, css, itd.)
     --html-extension \              # zapisz pliki z rozszerzeniem html
     --restrict-file-names=windows \ # eskejpuje znaki by Windows (są też inne tryby) sobie poradził
     --domains example.com \         # nie śledź linków poza domenom
     http://example.com
Podzieliłem problem na dwie części, ale pewnie da się to zamknąć do jednego polecenia.

17 lutego 2015

Parser na bazie własnej gramatyki - pyparsing

Czasami zachodzi potrzeba, przeanalizowania danych, na które nie ma dedykowanego parsera. Niekiedy wystarcza regexp, ale jeżeli struktury danych zaczynają być zagnieżdżone, można pokusić się o stworzenie gramatyki i skorzystanie z jakiejś biblioteki. Ponieważ dawno się już tym nie zajmowałem, nie przywiązywałem szczególnej uwagi, czy biblioteka pozwala na zapis zbliżony do notacji BNF (http://pl.wikipedia.org/wiki/Notacja_BNF).

Wybrałem pierwszą z brzegu, omówioną w wykładzie Erik Rose - "Parsing Horrible Things with Python":



Dokumentacja jest moim zdaniem kiepska (pierwszy link), ale następny link (wykład Paula McGuire) bardzo ułatwiły pracę:
Instalacja pyparsing w wersji 2.0.3.
pip install pyparsing
Przykład - wyciąganie liczby ze stringu, który może być wielokrotnie zamknięty za pomocą nawiasów < i >
import pyparsing as pp

startMark = pp.Suppress(pp.Literal('<'))
endMark = pp.Suppress(pp.Literal('>'))

greet = pp.Word(pp.alphas + ',')
value = pp.Word(pp.nums)
lastContent = greet + value

expr = pp.Forward()

content = pp.Group(expr).setResultsName('Indent') | \
          pp.Group(lastContent).setResultsName('Right Content')

expr << startMark + content + endMark

grammar = expr

data = '<<Hello, 1337>>'
res = grammar.parseString(data)
print(res)
print(type(res))
print(res[0].getName())
Wynik:
[[['Hello,', '1337']]]
<class 'pyparsing.ParseResults'>
Indent
Do budowania gramatyk, najlepiej korzystać z operatorów +, ^, |. Do dopasowania tekstu służy nam wiele obiektów (tokenów) np.
  • Word - dopasowuje tekst z dowolnego złożenia znaków
  • Literal - dopasowuje zwartość do znaków dokładnie w takiej kolejności jak zostały podane
  • Suppress - dopasowuje, ale zawartość zostanie pominięta w wyniku
Problemem może być dopasowywanie do zagnieżdżonych zawartości. Token w takim przypadku, powinien odwoływać się sam do siebie. Z pomocą przychodzi Forward(), a ostateczny opis należy wykonać za pomocą operatora << (linijka 14).
Group, pozwala na grupowanie wyników/tokenów jakie pojawią się w ostatecznym wyniku.
Słowo jeszcze o metodach, które okazały się w moim przypadku niezwykle przydane:
  • delimitedList(expression, delim=',') - dopasuje wyrażenie, rozdzielone za pomocą delimitera (domyślnie jest to przecinek)
  • Group.setResultsName() - nadaje nazwę do dopasowanego tokenu, ma niby posłużyć w celu zbudowania słownika ze sparsowanymi danymi, ale ja po prostu korzystam z getName() na wynikowych danych, gdy po nich iteruje
  • ParseResults.asList() - wynik domyślnie jest obiektem ParseResult, ale możemy skorzystać z konwersji i przekształcić go na listę