--- /dev/null
+//
+// C++ Implementation: code39
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "code39.h"
+
+#include <QMap>
+#include <QPainter>
+
+//order of characters for checksum calculation and list of allowed chars
+static const QString c39mod="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%";
+
+//init pixel map
+static QMap<char,QString> initmap()
+{
+ QMap<char,QString>map;
+ // 0=black 1=white pixel
+ map.insert('*',"0111010001000101");
+ map.insert('-',"0111010100010001");
+ map.insert('$',"0111011101110101");
+ map.insert('%',"0101110111011101");
+ map.insert(' ',"0111000101000101");
+ map.insert('.',"0001110101000101");
+ map.insert('/',"0111011101011101");
+ map.insert('+',"0111010111011101");
+ map.insert('0',"0101110001000101");
+ map.insert('1',"0001011101010001");
+ map.insert('2',"0100011101010001");
+ map.insert('3',"0001000111010101");
+ map.insert('4',"0101110001010001");
+ map.insert('5',"0001011100010101");
+ map.insert('6',"0100011100010101");
+ map.insert('7',"0101110100010001");
+ map.insert('8',"0001011101000101");
+ map.insert('9',"0100011101000101");
+ map.insert('A',"0001010111010001");
+ map.insert('B',"0100010111010001");
+ map.insert('C',"0001000101110101");
+ map.insert('D',"0101000111010001");
+ map.insert('E',"0001010001110101");
+ map.insert('F',"0100010001110101");
+ map.insert('G',"0101011100010001");
+ map.insert('H',"0001010111000101");
+ map.insert('I',"0100010111000101");
+ map.insert('J',"0101000111000101");
+ map.insert('K',"0001010101110001");
+ map.insert('L',"0100010101110001");
+ map.insert('M',"0001000101011101");
+ map.insert('0',"0101000101110001");
+ map.insert('O',"0001010001011101");
+ map.insert('P',"0100010001011101");
+ map.insert('Q',"0101010001110001");
+ map.insert('R',"0001010100011101");
+ map.insert('S',"0100010100011101");
+ map.insert('T',"0101000100011101");
+ map.insert('U',"0001110101010001");
+ map.insert('V',"0111000101010001");
+ map.insert('W',"0001110001010101");
+ map.insert('X',"0111010001010001");
+ map.insert('Y',"0001110100010101");
+ map.insert('Z',"0111000100010101");
+ return map;
+}
+//map characters on pixel codes
+static const QMap<char,QString>c39map=initmap();
+
+//calculate checksum
+static char code39mod(QString str)
+{
+ int sum=0;
+ for(int i=0;i<str.size();i++)
+ sum+=c39mod.indexOf(str[i]);
+ return c39mod[sum%43].toAscii();
+}
+
+QPixmap code39(QString str)
+{
+ //check string, return empty pixmap if invalid
+ str=str.toUpper();
+ for(int i=0;i<str.size();i++){
+ if(!c39mod.contains(str[i]))return QPixmap();
+ }
+ //create 01-list
+ QString rstr=c39map['*'];
+ for(int i=0;i<str.size();i++)
+ rstr+=c39map[str[i].toAscii()];
+ rstr+=c39map[code39mod(str)];
+ rstr+=c39map['*'];
+ //create pixmap
+ QPixmap pix(str.size()*16,1);
+ QPainter dev(&pix);
+ dev.setPen(Qt::black);
+ //paint
+ pix.fill(Qt::white);
+ for(int i=0;i<rstr.size();i++)
+ if(rstr[i]=='0')
+ dev.drawPoint(i,0);
+ return pix;
+}
--- /dev/null
+//
+// C++ Implementation: hmac
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "hmac.h"
+#include <QByteArray>
+
+SMHmac::SMHmac(QCryptographicHash::Algorithm algo,const QByteArray&key)
+ :subhashin(algo),subhashout(algo),state(Collecting)
+{
+ //calculate key schedules
+ QByteArray k2=key;
+ int hlen=blockWidth(algo);
+ if(k2.size()>hlen){
+ //hash the key if it is too long
+ k2=QCryptographicHash::hash(k2,algo);
+ }else
+ if(k2.size()<hlen){
+ //pad the key if it is too short
+ for(int i=k2.size();i<hlen;i++)
+ k2.append((char)0);
+ }
+ //mix with ipad/opad
+ for(int i=0;i<hlen;i++){
+ keyA.append(k2[i]^0x5c);
+ keyB.append(k2[i]^0x36);
+ }
+ //init hashes
+ subhashin.addData(keyB);
+ subhashout.addData(keyA);
+}
+void SMHmac::addData ( const char * data, int length ){addData(QByteArray(data,length));}
+void SMHmac::addData ( const QByteArray & data )
+{
+ //don't continue if already finished
+ if(state!=Collecting)return;
+ //add to inner hash
+ subhashin.addData(data);
+}
+
+void SMHmac::reset ()
+{
+ //reset hashes
+ subhashin.reset();
+ subhashout.reset();
+ //initialize
+ subhashin.addData(keyB);
+ subhashout.addData(keyA);
+ //reset state
+ state=Collecting;
+}
+
+QByteArray SMHmac::result()
+{
+ if(state==Finished){
+ return subhashout.result();
+ }else{
+ state=Finished;
+ subhashout.addData(subhashin.result());
+ return subhashout.result();
+ }
+}
+
+//static
+int SMHmac::resultWidth(QCryptographicHash::Algorithm a)
+{
+ switch(a){
+ case QCryptographicHash::Md4:return 128/8;
+ case QCryptographicHash::Md5:return 128/8;
+ case QCryptographicHash::Sha1:return 160/8;
+ //this is rather expensive, but Qt leaves me no choice
+ default: return QCryptographicHash::hash(QByteArray("a"),a).size();
+ }
+}
+
+//static
+int SMHmac::blockWidth(QCryptographicHash::Algorithm a)
+{
+ switch(a){
+ case QCryptographicHash::Md4:
+ case QCryptographicHash::Md5:
+ case QCryptographicHash::Sha1:return 64;
+ //FIXME: this should be in QCryptographicHash, since I can't know all its hashes!
+ default: return -1;
+ }
+}
+
+//static
+QByteArray SMHmac::hmac(const QByteArray&data,const QByteArray&key,QCryptographicHash::Algorithm method)
+{
+ SMHmac hm(method,key);
+ hm.addData(data);
+ return hm.result();
+}
--- /dev/null
+//
+// C++ Interface: hmac
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2007
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef SMOKE_HMAC_H
+#define SMOKE_HMAC_H
+
+#include <QCryptographicHash>
+
+class SMHmac
+{
+ public:
+ /**constructs an object that calculates HMACs*/
+ SMHmac(QCryptographicHash::Algorithm algo,const QByteArray&key);
+ /**adds length bytes of data to the hash-stream*/
+ void addData(const char * data, int length );
+ /**adds data to the hash-stream*/
+ void addData(const QByteArray & data );
+ /**reset the hash to the state immediately after construction*/
+ void reset();
+ /**finalize the hash and return the result*/
+ QByteArray result();
+
+ /**returns the length of the results of given algorithm in bytes; this should have been implemented by QCryptographicHash! performs a test calculation if the algo is unknown*/
+ static int resultWidth(QCryptographicHash::Algorithm);
+ /**returns the length of the blocks used internally in the given algorithm in bytes; this should have been implemented by QCryptographicHash! returns -1 if in doubt*/
+ static int blockWidth(QCryptographicHash::Algorithm);
+ /**complete HMAC calculation in a can*/
+ static QByteArray hmac(const QByteArray&data,const QByteArray&key,QCryptographicHash::Algorithm method);
+ private:
+ //the two key schedules
+ QByteArray keyA,keyB;
+ //remember where we are
+ enum State {Collecting,Finished};
+ mutable State state;
+ //inner hash function
+ QCryptographicHash subhashin,subhashout;
+};
+
+
+#endif