Related
Could you pls help me in this type of task.Actually I dont understand what I should provide as an answer
A given bit vector has length n. It is known that the vector can contain only two ones. A combinational system needs to calculate the distance between the ones. For example, in vector "10100" the distance is 2. Give the high-level specification.
When google turned up this SO question for me, I was pretty excited. I was hoping there'd be some code here I could repurpose. Alas, the OP's question was too abstract for a concrete solution to get proposed.
Still, for the next guy, here's at least /a/ solution, designed for MSVC x64:
#include <intrin.h> // __lzcnt64 & _BitScanForward64
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
/// <summary>
/// Given a pointer to an array of bits, prints out the distance between the bits.
/// </summary>
/// <param name="pBits">Pointer to the bits</param>
/// <param name="len">Length of the array in bytes</param>
/// <param name="carry">Previous value of carry</param>
/// <returns>Final carry</returns>
/// <remarks>Reading right to left, a bit pattern of 11100101 (aka 0xE5) will print 1, 2, 3, 1, 1</remarks>
uint64_t CountBitDistance(const uint8_t* pBits, const size_t len, uint64_t carry = 0)
{
// Assumes len divides evenly by 8. Depending on the platform,
// pBits might also need to be 8 byte aligned. Left as an exercise.
assert((len % 8) == 0);
const uint64_t* pUll = (const uint64_t*)pBits;
for (size_t x = 0; x < len / 8; pUll++, x++)
{
uint64_t ull = *pUll;
// Grab the value before we start modifying ull
const uint64_t newcarry = __lzcnt64(ull);
unsigned long res = 0;
// Returns false when ull is zero. res is zero based.
while (_BitScanForward64(&res, ull))
{
// Tempting though it might be, you can't just increment res and
// do both shifts at once. If the only bit set is the most
// significant one, adding 1 gives you 64. Shifting a 64bit value
// by 64 is undefined behavior in C. On x64 for example, it does
// nothing. If you are *sure* that res will never be 63, or if
// you are on a platform that handles shifts > 63 differently (and
// don't need a portable solution), you could combine them and
// increase perf (by a tiny amount).
// So, first get rid of the zeros...
ull >>= res;
// ... then turn off the bit we just found.
ull >>= 1;
// If we found a bit at position 0, we want to report 1.
res++;
// And apply any carry in from the previous ull.
const uint64_t d = carry + res;
// Carry in applied.
carry = 0;
printf("%llu\n", d);
}
// Remember that we might not go into the loop above at all, so carry
// won't necessarily be zero.
carry += newcarry;
}
// Useful if the source of our bits is continuing to produce data. We may
// need the final value from the previous batch to apply to the next.
return carry;
}
int main()
{
constexpr const uint8_t bits[] = {
0xAA, 0x25, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xAA, 0x25, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
};
constexpr const uint8_t bits2[] = { 0x2, 0, 0, 0, 0, 0, 0, 0 };
uint64_t t1 = CountBitDistance(bits, sizeof(bits));
printf("t1: %llu\n\n", t1);
uint64_t t2 = CountBitDistance(bits2, sizeof(bits2), t1);
printf("t2: %llu\n", t2);
}
No doubt someone else will pop up with a drastically better solution using some clever bit twiddling hacks. Still, at least now there's something.
I have some data that was encrypted using the openssl (AES_*) functions. I want update this code to use the newer (EVP_*) functions. But should be able to decrypt data that was encrypted using the old code.
I've pasted below both the old and the new code. The encrypted/decrypted contents are different. i.e. I can't use them interchangeably. This means I can't upgrade the code without having to decrypt using the old code and then re-encrypt.
Are there any values for the parameters to EVP_BytesToKey so that aes_key derived is the same in both cases. Or is there any other way to accomplish the same using the (EVP_*) functions? I've tried several different values for digest, rounds and tried making iv NULL, but didn't really work i.e. it doesn't provide the same output as the old method.
The code using the AES_* functions
#include <stdio.h>
#include <openssl/aes.h>
#include <print_util.h>
static const unsigned char user_key[] = {
0x00, 0x01, 0x02, 0x03,
0x10, 0x11, 0x12, 0x13,
0x20, 0x21, 0x22, 0x23,
0x30, 0x31, 0x32, 0x33
};
int main()
{
unsigned char p_text[]="plain text";
unsigned char c_text[16];
unsigned char d_text[16];
AES_KEY aes_key;
AES_set_encrypt_key(user_key, 128, &aes_key);
AES_encrypt(p_text, c_text, &aes_key);
printf("plain text = %s\n", p_text);
printbuf((char*)c_text, 16, "cipher text = ");
AES_set_decrypt_key(user_key, 128, &aes_key);
AES_decrypt(c_text, d_text, &aes_key);
printf("plain text (decrypted) = %s \n", d_text);
return 0;
}
The code using the EVP_* functions. (Encryption code is below and the decryption code is similar).
#include <strings.h>
#include <openssl/evp.h>
#include <print_util.h>
static const unsigned char user_key[16] = {
0x00, 0x01, 0x02, 0x03,
0x10, 0x11, 0x12, 0x13,
0x20, 0x21, 0x22, 0x23,
0x30, 0x31, 0x32, 0x33
};
int main()
{
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(ctx);
const EVP_CIPHER *cipher = EVP_aes_128_ecb(); // key size 128, mode ecb
const EVP_MD *digest = EVP_md5();
int rounds = 10;
unsigned char aes_key[EVP_MAX_KEY_LENGTH];
unsigned char aes_iv[EVP_MAX_IV_LENGTH];
EVP_BytesToKey(cipher, digest, NULL, user_key, 16, rounds, aes_key, aes_iv);
EVP_EncryptInit(ctx, cipher, aes_key, aes_iv);
unsigned char p_text[]="plain text"; int p_len = sizeof(p_text);
unsigned char c_text[16]; int c_len = 16;
int t_len;
EVP_EncryptUpdate(ctx, c_text, &c_len, p_text, p_len);
EVP_EncryptFinal(ctx, (c_text + c_len), &t_len);
c_len += t_len;
printf("==> p_text: %s\n", p_text);
printbuf((char*)c_text, c_len, "==> c_text:");
}
Thanks
You don't have any key derivation in your AES_* code, so you should not use any key derivation such as EVP_BytesToKey in your new EVP_ code if you want to stay fully compatible.
And no, there is no way to make EVP_BytesToKey output the same key as above, because a cryptographic hash is used to generate the output.
I'm attempting to send sensor data from an Arduino Uno via a Copperhead Wi-Fi shield to a specific IP address and port on a LAN.
I can get the Copperhead Wi-Fi Server example sketch to work (pasted below). However, I'm not interested in responding to server requests via HTML. All I'm interested in is setting up a socket-like connection and sending data via TCP or UDP to IP address 192.168.0.3, port 1234.
I'm sure there is an easy solution to this, but as I am new to Arduino and my attempts to find a solution have been unsuccessful.
#include <WiServer.h>
#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2
// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {192,168,0,2}; // IP address of WiShield
unsigned char gateway_ip[] = {192,168,0,1}; // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0}; // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"WiFi_AP"}; // max 32 bytes
unsigned char security_type = 0; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"12345678"}; // max 64 characters
// WEP 128-bit keys
// sample HEX keys
prog_uchar wep_keys[] PROGMEM = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, // Key 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3
};
// Setup the wireless mode
// Infrastructure - connect to AP
// Adhoc - connect to another Wi-Fi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// End of wireless configuration parameters ----------------------------------------
// This is our page serving function that generates web pages
boolean sendMyPage(char* URL) {
// Check if the requested URL matches "/"
if (strcmp(URL, "/") == 0) {
// Use WiServer's print and println functions to write out the page content
WiServer.print("<html>");
WiServer.print("Hello World");
WiServer.print("</html>");
// URL was recognized
return true;
}
// URL not found
return false;
}
void setup() {
// Initialize WiServer and have it use the sendMyPage function to serve pages
WiServer.init(sendMyPage);
// Enable Serial output and ask WiServer to generate log messages (optional)
Serial.begin(57600);
WiServer.enableVerboseMode(true);
}
void loop(){
// Run WiServer
WiServer.server_task();
delay(10);
}
Looks like you are using the WiShield library. There should be an examples folder in the WiShield download with a SocketApp and UDPApp example. This is a good place to start.
A few things I learned while making a UDP app.
You may have to edit some #defines (e.g. APP_UDPAPP in apps-conf.h, UIP_CONF_UDP in uip-conf.h) before recompiling your app.
If you are doing a UDP app, keep in mind that you have a limited receive buffer (UIP_CONF_BUFFER_SIZE in uip-conf.h sets it to 400). My router was sending out a UDP broadcast XML message that was ~700 bytes which caused this buffer to overflow and over write other data. I don't think TCP will have this problem because it will negotiate a MSS that won't overrun the buffer.
In the end I made changes to the handle_connection() function in the UDPapp example. Below is a snippet (with uip_ipaddr set to 255.255.255.255).
void send_state(void) {
sprintf((char*)uip_appdata, "state %ld %ld %ld %c %d",
clock_time(),
state.sensors.ping[0].cm,
state.sensors.ping[1].cm,
state.actuators.chassis.direction,
state.actuators.chassis.speed);
uip_send(uip_appdata, strlen((char*)uip_appdata));
}
void send_beacon(void) {
if(timer_expired(&beacon_timer)) {
timer_reset(&beacon_timer);
sprintf((char*)uip_appdata, "beacon %ld", clock_time());
uip_send(uip_appdata, strlen((char*)uip_appdata));
uip_log("beacon sent");
}
}
boolean data_or_poll(void) {
return (uip_newdata() || uip_poll());
}
static PT_THREAD(handle_connection(void)) {
PT_BEGIN(&s.pt);
PT_WAIT_UNTIL(&s.pt, data_or_poll());
if(uip_newdata()) {
uip_flags &= (~UIP_NEWDATA);
send_state();
} else if (uip_poll()) {
uip_flags &= (~UIP_POLL);
send_beacon();
}
PT_END(&s.pt);
}
Did you get a chance to look at the Arduino WiFiWebClient tutorial? This example shows how to connect to a webserver and send an HTTP GET request.
You could create a simple server on any machine on the LAN and use the client library to connect to the server and send data using the write/print/println set of functions. I know its easier said than done, but thats the fun of programming isnt it?
I am working on a project, and I am trying to get a grasp of it. Using the WiShield. I have been trying to complete the example program for a simple tweeter. However, I have had no luck yet. I have been trying to find the solutions, and everything I find never seems to work. How do I fix this problem?
My code is below as well as the errors I receive.
Code
#include <WiServer.h>
#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2
unsigned char local_ip[] = {192,168,2,2};
unsigned char gateway_ip[] = {192,168,2,1};
unsigned char subnet_mask[] = {255,255,255,0};
const prog_char ssid[] PROGMEM = {"myssid"};
unsigned char security_type = 3; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
const prog_char security_passphrase[] PROGMEM = {"mywifipassword"};
prog_uchar wep_keys[] PROGMEM = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3
};
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
// Authentication string for the Twitter account.
char* auth = "[user:pass]"; // Base64 encoded USERNAME:PASSWORD
// This function generates a message with the current system time.
void currentTime() {
WiServer.print("Arduino has been running for ");
WiServer.printTime(millis());
}
// A request that sends a tweet using the currentTime function.
TWEETrequest sentMyTweet(auth, currentTime);
void setup() {
// Initialize WiServer (we'll pass NULL for the page serving function since we don't need to serve web pages).
WiServer.init(NULL);
// Enable Serial output and ask WiServer to generate log messages (optional).
Serial.begin(57600);
WiServer.enableVerboseMode(true);
}
// Time (in milliseconds) when the next tweet should be sent.
long tweetTime = 0;
void loop(){
// Check if it's time to sent a tweet
if (millis() >= tweetTime) {
sentMyTweet.submit();
// Send next tweet 5 minutes from now
tweetTime += 1000 * 60 * 5;
}
// Run WiServer
WiServer.server_task();
delay(10);
}
Errors
In file included from SimpleTweeter.cpp:5:
C:\Program Files (x86)\arduino-1.0\libraries\WiShield/WiServer.h:198: error: conflicting return type specified for 'virtual void Server::write(uint8_t)'
C:\Program Files (x86)\arduino-1.0\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
SimpleTweeter.pde:-1: error: 'TWEETrequest' does not name a type
SimpleTweeter.cpp: In function 'void loop()':
SimpleTweeter.pde:-1: error: 'sentMyTweet' was not declared in this scope
(I am new to Arduino.)
It looks like the WiServer library hasn't been upgraded to work with Arduino 1.0. In this version of the Arduino software, the return type of the write method in the Print class was changed from void to size_t.
There is a fork of WiShield on GitHub by Juan C. Muller which makes it compatible with Arduino 1.0.
The subsequent error about the type TWEETrequest is a knock-on effect of this previous error.
Is there any way to calculate the largest outcome from an Rijndael encryption with a fixed array length?
Encryption method: RijndaelManaged
Padding: PKCS7
CipherMode: CBC
BlockSize 128
KeySize: 128
I need this as im converting a database where all string are going to be encrypted so i need to change the size of all string fields.
Everything you need to try this out:
public partial class Form1 : Form
{
private SymmetricAlgorithm mEncryptionType;
public Form1()
{
mEncryptionType = new RijndaelManaged();
mEncryptionType.Padding = PaddingMode.PKCS7; //PaddingMode.None;
mEncryptionType.Mode = CipherMode.CBC;
mEncryptionType.BlockSize = 128; // 192; // 256; // Update byte array to IV when changed
mEncryptionType.KeySize = 128; // 192; // 256; // Update byte array to Key when changed
mEncryptionType.IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
mEncryptionType.Key = new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
int encrypted_size = CalculateEncryptedSize(new byte[] { 0x22, 0x23, 0x44 });
// Shows Theran's point about exact block size
encrypted_size = CalculateEncryptedSize(new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF });
}
/// <summary>
/// Calculate the encrypted size of input buffer
/// </summary>
/// <param name="inputBuffer">The input buffer</param>
/// <returns>Size of the encrypted buffer</returns>
public int CalculateEncryptedSize(byte[] inputBuffer)
{
int extra_padding = 0;
if (mEncryptionType.Padding != PaddingMode.None)
{
int padding_size = (mEncryptionType.BlockSize / 8);
extra_padding = (padding_size - (inputBuffer.Length % padding_size));
}
return inputBuffer.Length + extra_padding;
}
}
Yes. Round up your input size to the nearest multiple of your block size (e.g. 128 / 8 = 16 bytes).
extraBytesNeeded = (16 - (inputSize % 16)) % 16;
maxSize = inputSize + extraBytesNeeded.
Jeff's answer is almost correct, except that PKCS7 will always add padding to the message, even if the message exactly fits inside an integral number of blocks. Also, don't forget that if using a random IV that the IV has to be stored too. The corrected formula for the length of a PKCS7 padded message is:
extraBytesNeeded = (16 - (inputSize % 16)); // whole block of padding if input fits exactly
maxSize = inputSize + extraBytesNeeded + IVbytes;