Im trying to create a one time password generator for a phone. In the RFC2289 it specifies that i must fold the output of the MD5, i'm using bouncy castle MD5 and i cant work out how to fold the byte array output.
for (int i = 0; i < 8; i++)
{
md5[i] ^= md5[i+8];
}
This is what i have so far
Probably, you want this:
for (int i = 0; i < 8; ++i)
md5[i] ^= md5[i + 8];
return Arrays.copyOf(md5, 8);
This way, only the first 64 bits (which are used by OTP) is returned.
Related
I found this post online (dates back to 2013) when I had trouble getting direct access to a specific cell in a vtkPolyData. I am using the latest version: VTK 8.1.1 and it seems like the newer version of VTK still has this issue.
polys->InitTraversal();
for(int i = 0; i < polys->GetNumberOfCells(); i++)
{
polys->GetNextCell(idList); // This sequential method gets the point IDs correctly
int a = idList->GetId(0);
int b = idList->GetId(1);
int c = idList->GetId(2);
}
However, the direct access method seems to have issues
polys->InitTraversal();
for(int i = 0; i < polys->GetNumberOfCells(); i++)
{
polys->GetCell(i, idList); // This method returns wrong ids
int a = idList->GetId(0);
int b = idList->GetId(1);
int c = idList->GetId(2);
}
How can I get the point IDs in a specific cell without looping through all the cell? Isn't polys->GetCell(i, idList) meant to give you direct access to a specific cell?
For direct access, we can use vtkPolyData::GetCellPoints() method. For example we can do
vtkNew<vtkIdList> idL; // or auto idL = vtkSmartPointer<vtkIdList>::New();
poly->GetCellPoints( 13, idL ); // Assuming you want the points for 13th cell
for(auto i = 0; i < idL->GetNumberOfIds(); ++i)
std::cout<< idL->GetId(i) << std::endl;
For looping over all cells I prefer a while loop:
vtkNew<vtkIdList> idL;
poly->GetPolys()->InitTraversal();
while(poly->GetPolys()->GetNextCell(idL)){
for(auto i = 0; i < idL->GetNumberOfIds(); ++i)
std::cout<< idL->GetId(i) << std::endl;
}
I'm trying to write my first real program with dynamic arrays, but I've come across a problem I cannot understand. Basically, I am trying to take a dynamic array, copy it into a temporary one, add one more address to the original array, then copy everything back to the original array. Now the original array has one more address than before. This worked perfectly when trying with ints, but strings crash my program. Here's an example of the code I'm struggling with:
void main()
{
int x = 3;
std::string *q;
q = new std::string[x];
q[0] = "1";
q[1] = "2";
q[2] = "3";
x++;
std::string *temp = q;
q = new std::string[x];
q = temp;
q[x-1] = "4";
for (int i = 0; i < 5; i++)
std::cout << q[i] << std::endl;
}
If I were to make q and temp into pointers to int instead of string then the program runs just fine. Any help would be greatly appreciated, I've been stuck on this for an hour or two.
q = temp performs only a shallow copy. You lose the original q and all of the strings it pointed to.
Since you reallocated q to have 4 elements, but then immediately reassigned temp (which was allocated with only 3 elements), accessing (and assigning) the element at x now is outside the bounds of the array.
If you have to do it this way for some reason, it should look like this:
auto temp = q;
q = new std::string[x];
for(int x = 0; x < 3; ++x)
q[x] = temp[x];
delete [] temp;
q[x] = 4;
However, this is obviously more complex and very much more prone to error than the idiomatic way of doing this in C++. Better to use std::vector<std::string> instead.
In python i can write
s = "dad" * 3
Result will be: s = "daddaddad"
I want to append "tabs" to my string. Something like:
QString tabs = "\t" * count;
What would be a simple, idiomatic way to do it?
You can do it quite simply with a loop:
QString mystring("somestring");
QString output;
for (int i = 0; i < 3; ++i)
output.append(mystring);
//'output' will contain the result string
Please note that the code I provide is in C++, not Python, but the concept still applies (and should be easily ported).
EDIT:
If you need to concatenate single characters, you could do it more easily like this:
int size = 5;
QString output(size, QChar('\t'));
//'output' contains 5 tab characters
Or, if you need to assign to another string (output is already created):
int size = 5;
output.fill(QChar('\t'), size);
//'output' contains 5 tab characters
#include <QString>
QString s;
for(int i = 0; i < 3; ++i)
{
s << "dad";
}
this is what i have of the function so far. This is only the beginning of the problem, it is asking to generate the random numbers in a 10 by 5 group of numbers for the output, then after this it is to be sorted by number size, but i am just trying to get this first part down.
/* Populate the array with 50 randomly generated integer values
* in the range 1-50. */
void populateArray(int ar[], const int n) {
int n;
for (int i = 1; i <= length - 1; i++){
for (int i = 1; i <= ARRAY_SIZE; i++) {
i = rand() % 10 + 1;
ar[n]++;
}
}
}
First of all we want to use std::array; It has some nice property, one of which is that it doesn't decay as a pointer. Another is that it knows its size. In this case we are going to use templates to make populateArray a generic enough algorithm.
template<std::size_t N>
void populateArray(std::array<int, N>& array) { ... }
Then, we would like to remove all "raw" for loops. std::generate_n in combination with some random generator seems a good option.
For the number generator we can use <random>. Specifically std::uniform_int_distribution. For that we need to get some generator up and running:
std::random_device device;
std::mt19937 generator(device());
std::uniform_int_distribution<> dist(1, N);
and use it in our std::generate_n algorithm:
std::generate_n(array.begin(), N, [&dist, &generator](){
return dist(generator);
});
Live demo
Short version: How can I turn an arbitrary string into a 6-digit number with minimal collisions?
Long version:
I'm working with a small library that has a bunch of books with no ISBNs. These are usually older, out-of-print titles from tiny publishers that never got an ISBN to begin with, and I'd like to generate fake ISBNs for them to help with barcode scanning and loans.
Technically, real ISBNs are controlled by commercial entities, but it is possible to use the format to assign numbers that belong to no real publisher (and so shouldn't cause any collisions).
The format is such that:
978-0-01-######-?
Gives you 6 digits to work with, from 000000 to 999999, with the ? at the end being a checksum.
Would it be possible to turn an arbitrary book title into a 6-digit number in this scheme with minimal chance of collisions?
After using code snippets for making a fixed-length hash and calculating the ISBN-13 checksum, I managed to create really ugly C# code that seems to work. It'll take an arbitrary string and convert it into a valid (but fake) ISBN-13:
public int GetStableHash(string s)
{
uint hash = 0;
// if you care this can be done much faster with unsafe
// using fixed char* reinterpreted as a byte*
foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s))
{
hash += b;
hash += (hash << 10);
hash ^= (hash >> 6);
}
// final avalanche
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
// helpfully we only want positive integer < MUST_BE_LESS_THAN
// so simple truncate cast is ok if not perfect
return (int)(hash % MUST_BE_LESS_THAN);
}
public int CalculateChecksumDigit(ulong n)
{
string sTemp = n.ToString();
int iSum = 0;
int iDigit = 0;
// Calculate the checksum digit here.
for (int i = sTemp.Length; i >= 1; i--)
{
iDigit = Convert.ToInt32(sTemp.Substring(i - 1, 1));
// This appears to be backwards but the
// EAN-13 checksum must be calculated
// this way to be compatible with UPC-A.
if (i % 2 == 0)
{ // odd
iSum += iDigit * 3;
}
else
{ // even
iSum += iDigit * 1;
}
}
return (10 - (iSum % 10)) % 10;
}
private void generateISBN()
{
string titlehash = GetStableHash(BookTitle.Text).ToString("D6");
string fakeisbn = "978001" + titlehash;
string check = CalculateChecksumDigit(Convert.ToUInt64(fakeisbn)).ToString();
SixDigitID.Text = fakeisbn + check;
}
The 6 digits allow for about 10M possible values, which should be enough for most internal uses.
I would have used a sequence instead in this case, because a 6 digit checksum has relatively high chances of collisions.
So you can insert all strings to a hash, and use the index numbers as the ISBN, either after sorting or without it.
This should make collisions almost impossible, but it requires keeping a number of "allocated" ISBNs to avoid collisions in the future, and keeping the list of titles that are already in store, but it's information that you would most probably want to keep anyway.
Another option is to break the ISBN standard and use hexadecimal/uuencoded barcodes, that may increase the possible range to a point where it may work with a cryptographic hash truncated to fit.
I would suggest that since you are handling old book titles, which may have several editions capitalized and punctuated differently, I would strip punctuation, duplicated whitespaces and convert everything to lowercase before the comparison to minimize the chance of a technical duplicate even though the string is different (Unless you want different editions to have different ISBNs, in that case, you can ignore this paragraph).