bool addRecursive(CuckooMap* map, uint64_t key, uint64_t value, int depth)
{
	if(depth > MAX_LOOP)
	{
		return false;
	}
	//if its empty in the first table, add it there
	if(getKey1(map, key) == NONE)
	{
		set1(map, key, value);
	}
	//if its empty in the second table, add it there
	else if(getKey2(map, key) == NONE)
	{
		set2(map, key, value);
	}
	//if both are occupied, randomly displace one and re-add the displaced one
	else if((xorshf96() & 1) == 0)
	{
		uint64_t pushedKey = getKey1(map, key);
		uint64_t pushedValue = getValue1(map, key);
		set1(map, key, value);
		return addRecursive(map, pushedKey, pushedValue, depth + 1);
	}
	else
	{
		uint64_t pushedKey = getKey2(map, key);
		uint64_t pushedValue = getValue2(map, key);
		set2(map, key, value);
		return addRecursive(map, pushedKey, pushedValue, depth + 1);
	}
	return true;
}
void removeCuckooMap(CuckooMap* map, uint64_t key)
{
	if(key == getKey1(map, key))
	{
		clear1(map, key);
	}
	if(key == getKey2(map, key))
	{
		clear2(map, key);
	}
	if(findCuckooOptimized(map, key) != CUCKOO_NOT_FOUND)
	{
		//assuming that the key was originally in this map, there's an error
		puts("Error with Removing");
		exit(1);
	}
}
/**
 * get one of VK_xxx
 */
uint8_t KeypadChannel::getKey()
{
  //analogRead(m_bPin);                     // switch the channel to m_bPin and hold for 104µs
  int adc_key_in = analogRead(m_bPin);    // read the value from the sensor 
  // 1st option for speed reasons since it will be the most likely result
  if(adc_key_in > 950) {
    //DEBUG_PRINTLN("Keypad::getKey() => VK_NONE");
    return VK_NONE;
  }    
  //DEBUG_PRINT("analogRead(m_bPin="); DEBUG_PRINTDEC(m_bPin); DEBUG_PRINT(") =>"); DEBUG_PRINTDEC(adc_key_in); DEBUG_PRINTLN("");  
  switch(m_uKeys)
  {
    case 2:
      return getKey2(adc_key_in);
    case 3:
      return getKey3(adc_key_in);
    case 4:
      return getKey4(adc_key_in);
    default:
      DEBUG_PRINTLN("KeypadChannel::getKey() wrong m_uKeys");
  }
  return VK_NONE;
}
void SessionParser::parse(const boost::uint8_t* p_data, boost::uint16_t p_length, boost::uint32_t p_srcAddr)
{
    switch(m_state) {
        case k_none:
            if (p_length > 13 && memcmp(p_data, "POST /jsproxy", 13) == 0) {
                std::cout << "[+] Initial request found." << std::endl;
                m_state = k_request;
            }
            break;
        case k_request:
            if (p_length > 17 && memcmp(p_data, "HTTP/1.1 200 OK\r\n", 17) == 0) {
                std::cout << "[+] Server challenge received." << std::endl;
                m_serverAddress = p_srcAddr;
                std::string packet;
                packet.assign(reinterpret_cast<const char*>(p_data), p_length);
                if (moveToPayload(packet) && packet.length() > 32) {
                    std::size_t index = 0;
                    for (std::size_t i = 0; i < 24 && index < packet.length(); i++) {
                        if (i < 8) {
                            codePointAt(packet, index);
                        } else {
                            m_rchallenge.push_back(codePointAt(packet, index));
                        }
                    }
                }
                m_state = k_challenge;
            }
            break;
        case k_challenge:
        {
            if (p_length < 13 || memcmp(p_data, "POST /jsproxy", 13) != 0) {
                break;
            }

            std::cout << "[+] Challenge response found." << std::endl;
            m_state = k_done;

            std::string packet;
            packet.assign(reinterpret_cast<const char*>(p_data), p_length);
            if (!moveToPayload(packet)) {
                std::cerr << "Failed to find the payload." << std::endl;
                break;
            }
            std::size_t index = 0;
            for (std::size_t i = 0; i < 26; i++) {
                codePointAt(packet, index);
            }
            m_lchallenge.assign(packet.data() + index, 16);
            index += 16;
            for (std::size_t i = 0; i < 8; i++) {
                codePointAt(packet, index);
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response1.push_back(codePointAt(packet, index));
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response2.push_back(codePointAt(packet, index));
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response3.push_back(codePointAt(packet, index));
            }
            m_response.assign(m_response1);
            m_response.append(m_response2);
            m_response.append(m_response3);
            m_username.assign(packet.data() + index, packet.length() - index);
            std::cout << "Username: "******"Failed to recover key3!" << std::endl;
                return;
            }
            std::cout << "DES Key 3: ";
            printHexString(key3, true);

            // guess des key 2
            std::string key2;
            if (!getKey2(key2, m_response2, challengeHash)) {
                std::cerr << "Failed to recover key2!" << std::endl;
                return;
            }
            std::cout << "DES Key 2: ";
            printHexString(key2, true);

            // guess des key 1
            std::string key1;
            if (!getKey1(key1, m_response1, challengeHash)) {
                std::cerr << "Failed to recover key1!" << std::endl;
                return;
            }
            std::cout << "DES Key 1: ";
            printHexString(key1, true);

            // retrieve the pwdhash from our 3 keys
            std::string pwdHash(makePwdHash(key1));
            pwdHash.append(makePwdHash(key2));
            pwdHash.append(makePwdHash(key3));
            pwdHash.resize(16);
            std::cout << "Password SHA-1: ";
            printHexString(pwdHash);

            // create the pwd hash hash for master key creation
            std::string pwdHashHash(MD4::md4(pwdHash));
            std::cout << "SHA-1(Password SHA-1): ";
            printHexString(pwdHashHash);

            // create the master key
            std::string masterKey(pwdHashHash);
            masterKey.append(m_response);
            masterKey.append("This is the MPPE Master Key");

            unsigned char sharesult[20] = { 0 };
            sha1::calc(masterKey.data(), masterKey.size(), sharesult);
            masterKey.assign((char*)sharesult, 16);
            std::cout<< "Master Key: ";
            printHexString(masterKey);
        }
            break;
        case k_challenge_response:
        case k_decrypt:
        case k_done:
        default:
            break;
    }
}
void MidiNoteInRangeBlock::getAdditionalState(QJsonObject& state) const {
	state["key"] = getKey();
	state["key2"] = getKey2();
	state["channel"] = getChannel();
    state["useDefaultChannel"] = getUseDefaultChannel();
}