Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer

JawnV6 posted:

Hate conditional logic? Smuggle the decisionmaking through flow control instead!

All of my source files start with a macro to inline branch-if-equals :v:

Adbot
ADBOT LOVES YOU

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

JawnV6 posted:

Hate conditional logic? Smuggle the decisionmaking through flow control instead!

Yeah, unless specifically asked for a recursive, general-for-all-N solution I don't think I would ever produce the recursive formulation of this problem. It's vastly simpler to just write out the conditionals. There's a bunch of nontrivial cases in the small sets, and it's much harder to verify that it really does work in the constrained number of experiments allowed.

raminasi
Jan 25, 2005

a last drink with no ice

This is cool, and the principle seems totally reasonable to me, just not the effort spent in formalizing it in non-general cases. (Which you agree with.) But my Haskell isn't good enough - can this determine the direction of the mid-weighted coin in the given number of experiments? That's part of the original problem. (Obviously it's just one more experiment, so the big-O complexity doesn't change.)

LeftistMuslimObama posted:

It involves a bunch of return statements instead. I didn't say no conditional logic, just fewer if statements. I also didn't think about it too hard so I'm probably missing a corner case in there.

how do you figure out which return statement executes

The MUMPSorceress
Jan 6, 2012


^SHTPSTS

Gary’s Answer
Full disclosure, I'm probably just a little overobsessed with writing recursive answers to everything because it tickles my nerdzones. I spend all day staring at languages where recursion is basically impossible so it's my default first thing to try when handed trivial problems outside the context of work.

I don't think we use that particular question in our interviews, and now that I've actually given it more than 5 seconds thought I agree that specific problem is maybe not great. I was more reacting to the general notion that trivial problems mean the interview is bad. I think they can have value in guiding the interview.

sarehu
Apr 20, 2007

(call/cc call/cc)
I'm real confused about this "thicket" of conditional logic.

code:
int x = unequal_weight(4, 5) ? 4 : unequal_weight(2, 3) * 2;
return x + !unequal_weight(x, (x + 2) % 6);

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

GrumpyDoctor posted:

But my Haskell isn't good enough - can this determine the direction of the mid-weighted coin in the given number of experiments? That's part of the original problem. (Obviously it's just one more experiment, so the big-O complexity doesn't change.)

My algorithm doesn't attempt to determine that information. It's sort of conflated; on some paths it will have performed the right experiment to learn that information, but in other paths it won't and would need an additional experiment.

Edit: To be more specific, you would probably elect to extract that information post-facto; once you know the identity of the mis-weighted coin, you look through past experiments to find any experiment which involved that coin. That experiment will tell you the direction of the weight difference. It's possible with 6 coins to get an answer without ever actually weighing the mis-weighted coin (e.g. sets [1,2] and [3,4] are equal, coins 1 and 5 are equal, mis-weighted coin must be 6 which has never been weighed) but I think without examining that too closely that you will always have a "left over" experiment available that you can use. I'm not really interested in rewriting my algorithm to verify that, though.

ShoulderDaemon fucked around with this message at 20:41 on Nov 19, 2015

raminasi
Jan 25, 2005

a last drink with no ice

sarehu posted:

I'm real confused about this "thicket" of conditional logic.

code:
int x = unequal_weight(4, 5) ? 4 : unequal_weight(2, 3) * 2;
return x + !unequal_weight(x, (x + 2) % 6);

Clear, intuitive, and complete code, shrughes-style.

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker

sarehu posted:

I'm real confused about this "thicket" of conditional logic.

code:
int x = unequal_weight(4, 5) ? 4 : unequal_weight(2, 3) * 2;
return x + !unequal_weight(x, (x + 2) % 6);

Too terse. Let me clean it up a little:

code:
// return coin
int x = unequal_weight(4, 5) ? 4 : unequal_weight(2, 3) * 2;
return x + !unequal_weight(x, (x + 2) % 6);

sarehu
Apr 20, 2007

(call/cc call/cc)
I guess we didn't really need any conditions.
code:
int x = unequal_weight(4, 5) * 4 + unequal_weight(2, 3) * 2;
return x + !unequal_weight(x, (x + 2) % 6);
Too many multiplications and additions, let's optimize that a bit.

code:
int x = (unequal_weight(2, 3) << 1) | unequal_weight(0, 1);
return x ^ !unequal_weight(x, x + 2);
Edit: Oh wait hrm no.

code:
int x = (unequal_weight(4, 5) << 2) | (unequal_weight(2, 3) << 1);
return x ^ !unequal_weight(x, x - 2 + (!x << 2));
There.

sarehu fucked around with this message at 00:20 on Nov 20, 2015

raminasi
Jan 25, 2005

a last drink with no ice
Now instead of only satisfying the problem requirements if the fake coin is in one of the last two positions, it never satisfies them. Hooray for consistency!

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Man, if one of my coworkers used code like that in real life I would punch them so hard.

I mean, code golf is a thing, sure, I just wouldn't want to see it used in an interview.

sarehu
Apr 20, 2007

(call/cc call/cc)

GrumpyDoctor posted:

Clear, intuitive, and complete code, shrughes-style.

First you pick the pair, of (0,1), (2,3), or (4,5) that has the bad coin, in two comparisons. Then you use one more to see if the even number is the bad one.

How is that bad?

JawnV6
Jul 4, 2004

So hot ...

sarehu posted:

First you pick the pair, of (0,1), (2,3), or (4,5) that has the bad coin, in two comparisons. Then you use one more to see if the even number is the bad one.

How is that bad?
You spent two comparisons checking 0v1, 2v3, which come back equivalent. You've isolated the bad coin to 4,5. Now you have 1 comparison to determine two facts, which coin is bad and if it's over or under weight. You can figure out one of them with 1v4 or 4v5, but how do you extract both bits without getting lucky?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
6 coins in 3 weighings is easy-mode anyway. If you want to have to actually think about it, try 12 coins. (In theory, you have enough information for 13, but you'd need something extra in order to extract maximum information out of the very first weighing.)

Rockybar
Sep 3, 2008

I've just started processing, and I'm trying to write software which will sort the data output from the serial of an Arduino. Currently the arduino's output looks like this:
code:
Compass
43.04
HR
-604.89
Compass
43.12
HR
-700.00
Compass
43.28
.......
and so on. So in my processing I wrote some code to check the string outputs, and then to read the following line (it switches into HR (heart rate mode), and Compass mode). But it doesn't seem to work. The code is supposed to sort the two inputs, and then take a reading from the next line, until it switches back into the other mode.
code:
   if ( myPort.available() > 0) // If data is available,
          {  
                val = myPort.readStringUntil('\n');         // read it and store it in val
          } 
code:
        if (val.equals("Compass"))
          {
            beatmode = false;
            compassMode = true;  
            text("Hello ",180,80);   //test if the compass mode has been activated
          }
          
        else if (val.equals("HR"))
          {
            beatmode = true;
            compassMode = false;
          }
            
        if (compassMode && !val.equals("Compass"))   // compass readings
          {
            ...some code......
          }   
                
        if (beatmode && !val.equals("HR"))
          {
           ....some code....
              
            beatmode = false; 
            }
            
        }
Am I reading these strings incorrectly, or perhaps the serial? When I come to display the data in my GUI both outputs are simply stuck at 0. Many thanks for any help.

edit: I've also checked if any commands are deleting the outputs before they can be drawn in the program, but this doesn't seem to be the case.

edit 2: here's the full code just in case i'm missing crucial information: http://pastebin.com/eiCBPgG2

Rockybar fucked around with this message at 02:20 on Nov 20, 2015

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.

Sex Bumbo posted:

"no I'm not answering this dumb question"
or
"hold on let me google this because that's what I'd do in a real life scenario"

I've done that (sort of). I got a string processing interview question with the instructions to write a function to solve it like I would for real production code. I said I'd use a couple regular expression substitutions, but I don't remember what the syntax is for the regex library in this language, and in real life I'd google it. Interviewer said that's fine what are the substitutions you'd do? Got the job.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Rockybar posted:

I've just started processing, and I'm trying to write software which will sort the data output from the serial of an Arduino. Currently the arduino's output looks like this:
code:
Compass
43.04
HR
-604.89
Compass
43.12
HR
-700.00
Compass
43.28
.......
and so on. So in my processing I wrote some code to check the string outputs, and then to read the following line (it switches into HR (heart rate mode), and Compass mode). But it doesn't seem to work. The code is supposed to sort the two inputs, and then take a reading from the next line, until it switches back into the other mode.
code:
   if ( myPort.available() > 0) // If data is available,
          {  
                val = myPort.readStringUntil('\n');         // read it and store it in val
          } 
code:
        if (val.equals("Compass"))
          {
            beatmode = false;
            compassMode = true;  
            text("Hello ",180,80);   //test if the compass mode has been activated
          }
          
        else if (val.equals("HR"))
          {
            beatmode = true;
            compassMode = false;
          }
            
        if (compassMode && !val.equals("Compass"))   // compass readings
          {
            ...some code......
          }   
                
        if (beatmode && !val.equals("HR"))
          {
           ....some code....
              
            beatmode = false; 
            }
            
        }
Am I reading these strings incorrectly, or perhaps the serial? When I come to display the data in my GUI both outputs are simply stuck at 0. Many thanks for any help.

edit: I've also checked if any commands are deleting the outputs before they can be drawn in the program, but this doesn't seem to be the case.

edit 2: here's the full code just in case i'm missing crucial information: http://pastebin.com/eiCBPgG2

Any reason you can't just read the additional expected input immediately?

code:

phone post pseudocode

if ( myPort.available() > 0) // If data is available,
{  
  String mode = myPort.readStringUntil('\n');
  if("HR".equals(mode)) {
    String rateString = myPort.readStringUntil("\n");
    // do something with the heart rate
  } else if ("compass".equals(mode)) {
    String orientationString = myPort.readStringUntil("\n");
    // do something with the orientation
  }
}

Rockybar
Sep 3, 2008

Volmarias posted:

Any reason you can't just read the additional expected input immediately?


I could but the issue is once I've cleared up my code a bit I don't think it would work, because it will reach a point where they might be 10 Heart rate outputs before a compass one i.e.e [HR, 70, 60, 65, 54, 70, COMPASS, 98, HR, 20, 52...]. And I'd also like to add new modes quite easily. And I'm still not sure why my code isn't working correctly, is it an issue reading the val output?

edit: I really feel it has to be something to do with the if (val.equals("COMPASS")), is it because of the new line?

Rockybar fucked around with this message at 11:37 on Nov 20, 2015

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Rockybar posted:

I could but the issue is once I've cleared up my code a bit I don't think it would work, because it will reach a point where they might be 10 Heart rate outputs before a compass one i.e.e [HR, 70, 60, 65, 54, 70, COMPASS, 98, HR, 20, 52...]. And I'd also like to add new modes quite easily. And I'm still not sure why my code isn't working correctly, is it an issue reading the val output?

edit: I really feel it has to be something to do with the if (val.equals("COMPASS")), is it because of the new line?

OK, that wasn't clear because your sample input had each type only emitting a value once. Assuming that you cannot for some reason change the arduino firmware to work that way, since that would likely simplify both the code on the arduino and the java client, you probably do have to do something like what you had.

The documentation for readStringUntil isn't very clear. But, looking at the source, that calls readBytesUntil, whose doc states "Reads from the port into a buffer of bytes up to and including a particular character." That means that you need to compare against "HR\n" and "Compass\n".

When in doubt, use the debugger to see what input you're actually getting.

Rockybar
Sep 3, 2008

Volmarias posted:

OK, that wasn't clear because your sample input had each type only emitting a value once. Assuming that you cannot for some reason change the arduino firmware to work that way, since that would likely simplify both the code on the arduino and the java client, you probably do have to do something like what you had.

The documentation for readStringUntil isn't very clear. But, looking at the source, that calls readBytesUntil, whose doc states "Reads from the port into a buffer of bytes up to and including a particular character." That means that you need to compare against "HR\n" and "Compass\n".

When in doubt, use the debugger to see what input you're actually getting.

Sorry should have been clearer about that. This is really baffling me because with the if (val != null) {} statement, which I can confirm is working, not even a statement like
code:
           if (val.equals("\n"))
          {
            text("Hello ",180,80);      
          }
functions,. I tried declaring a new compass string:
code:
String compass = new String("COMPASS/n");
, (with and wihtout the '/n') and then using the comparison

code:
if (val.equals(compass))
          {
            beatmode = false;
            compassMode = true;  
            text("Hello ",180,80);
            q++;
          }
but that also brings up nothing. I know there isn't an issue reading from the serial because I can read just compass data on its own (no text, just new bearings each line). You're right about simplifying code but because the compass is digital and the heart rate reader analogue, i need a continuous stream of value from the heart rate monitor so I can plot an ECG-style curve. Also the debugger isn't listing any variables, if that helps.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

Rockybar posted:

code:
String compass = new String("COMPASS/n");

Dunno if this is just a typo or not, but your backslash is a frontslash here.

Rockybar
Sep 3, 2008

TooMuchAbstraction posted:

Dunno if this is just a typo or not, but your backslash is a frontslash here.

Cheers, changed it but didn't seem to fix it.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Have you considered looking at what input you're getting? Processing's IDE should have a debugger. At worst, put it into your text(...) calls to see what you're getting.

Rockybar
Sep 3, 2008

Volmarias posted:

Have you considered looking at what input you're getting? Processing's IDE should have a debugger. At worst, put it into your text(...) calls to see what you're getting.

I've tried that, just doing text(val, 100,100); in the normal loop, without modifying it, and it comes through fine, flashing up the value every refresh, as one would expect on the serial monitor, just shows COMPASS, or HR, or some reading on its own.

edit: about to go to sleep but in the morning I think I will try something like declaring a string = COMPASS, and then testing that against my if statements, to see if the equator is even working

Rockybar fucked around with this message at 01:31 on Nov 21, 2015

Turkeybone
Dec 9, 2006

:chef: :eng99:
Not sure if this is the right place, but, here goes (tl;dr I want to run automated reports but have no clue where to begin):

I work in widget sales, and the first part of each morning I have to update our widget progress to the team, via excel spreadsheets that are emailed. The basic process is:

Open Excel template

Open query in <some crappy, proprietary database view>
Copy results to clipboard, paste into an Excel tab.

Repeat for 15-20 queries.

I wrote a python script where I can do this automatically, so I come into work, double click and then go make a coffee or whatever. The database access we get is so lame, the python code is pretty much keystrokes to get to the saved queries in folders, switch to excel, advance tabs, etc; I can't really get to it in any useful way other than having this db viewer program and excel. But the next step I want to take is to be able to just run this at 5am or whatever, but I'm not really sure from where. Ideas are to leave my work laptop at work, always on, and have some timed execution. Or from home and vpn in.. but shouldn't there be some way I can run a version of this crappy db viewer and excel in the cloud, vpn into my work network, and then access the results in the morning?

If someone could point me in the direction of an answer, it would be greatly appreciated -- my specific widget business is not really a tech savvy one, so there's not much support available for the kinds of things I am trying to do here.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Turkeybone posted:

Not sure if this is the right place, but, here goes (tl;dr I want to run automated reports but have no clue where to begin):

I work in widget sales, and the first part of each morning I have to update our widget progress to the team, via excel spreadsheets that are emailed. The basic process is:

Open Excel template

Open query in <some crappy, proprietary database view>
Copy results to clipboard, paste into an Excel tab.

Repeat for 15-20 queries.

I wrote a python script where I can do this automatically, so I come into work, double click and then go make a coffee or whatever. The database access we get is so lame, the python code is pretty much keystrokes to get to the saved queries in folders, switch to excel, advance tabs, etc; I can't really get to it in any useful way other than having this db viewer program and excel. But the next step I want to take is to be able to just run this at 5am or whatever, but I'm not really sure from where. Ideas are to leave my work laptop at work, always on, and have some timed execution. Or from home and vpn in.. but shouldn't there be some way I can run a version of this crappy db viewer and excel in the cloud, vpn into my work network, and then access the results in the morning?

If someone could point me in the direction of an answer, it would be greatly appreciated -- my specific widget business is not really a tech savvy one, so there's not much support available for the kinds of things I am trying to do here.

To run your script automatically, you want the Windows Task Scheduler http://blogs.esri.com/esri/arcgis/2013/07/30/scheduling-a-scrip/ You can even configure the job to wake up the machine at 5 to run - it's just a check box you can click. Not sure about automating your VPN access.

The setup for a dedicated machine to run it depends a lot on your IT department and how paranoid they are, but the easy/simple way would be an old machine sitting in a corner in the office. You could also set up an AWS instance to do it if you wanted, but I don't have an article to link to about that.

Turkeybone
Dec 9, 2006

:chef: :eng99:
Perfect, thanks -- yeah I am a little remiss in asking my IT department about it (they were really.. weird.. when I asked them about GPS coords for our customer base (widget delivery is also part of our world)), so I'll try leaving my work laptop here a few nights to get it going, then look into some AWS (it's a small enough widget operation that I could probably do the majority of it for free).

mobby_6kl
Aug 9, 2009

by Fluffdaddy
I'd recommend against using AWS to connect to your internal database systems. Either you'll have to set up VPN from there, run plaintext data over the internet, or otherwise poke holes in your network. I can't imagine IT being particularly happy if they find out.

Our organization has our own cloud infrastructure that we can use for stuff like this, but since you probably don't have that, you could also run the process in a virtual machine - this won't help with the scheduling (at least on its own - maybe you could get IT to host it on an existing sever), obviously, but this way you could run it without the script interfering with your work or vice versa.

Turkeybone
Dec 9, 2006

:chef: :eng99:
So that's the thing, I wouldn't connect directly as in able to make changes -- I only can view using my cruddy viewer. So I guess I am thinking (maybe incorrectly so) that I need a machine with excel and my database viewer, and the choices are either my work laptop, my home desktop (via vpn), an IT server, or an Amazon AWS thing (again with vpn).

edit: looks like there is a means to automate turning on/off vpn connections as well, so that's progress: http://serverfault.com/questions/163772/how-to-automate-turning-on-off-windows-vpn-connection

Turkeybone fucked around with this message at 17:47 on Nov 23, 2015

lunar detritus
May 6, 2009


I have been editing some javascript code that's very efficient but hard to understand. Basically it takes a nested json and with recursion it transforms it into a matrix of objects and arrays to make it easier to transform into an html table.

I work mostly in angular and other javascript libraries but this feels lower level, computer scienciesh I guess?

How can I get to the level where that kind of code is natural to me? What should I read?

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

gmq posted:

I have been editing some javascript code that's very efficient but hard to understand. Basically it takes a nested json and with recursion it transforms it into a matrix of objects and arrays to make it easier to transform into an html table.

I work mostly in angular and other javascript libraries but this feels lower level, computer scienciesh I guess?

How can I get to the level where that kind of code is natural to me? What should I read?

There's no book to read that will make such things natural to you, you just need to work with code at that level for awhile.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

gmq posted:

I have been editing some javascript code that's very efficient but hard to understand. Basically it takes a nested json and with recursion it transforms it into a matrix of objects and arrays to make it easier to transform into an html table.

I work mostly in angular and other javascript libraries but this feels lower level, computer scienciesh I guess?

How can I get to the level where that kind of code is natural to me? What should I read?

Start with a naive solution that you can get to work, then account for edge cases, then find places you can optimize.

LP0 ON FIRE
Jan 25, 2006

beep boop
mysql/php/encryption advice needed!

I'm using mcrypt_encrypt to store base64 values in a db's table. I'm setting up a scheme where I have encrypted values on one database's table, and on another server's database I have a table their IV's. Every row of the encrypted values have a corresponding IV. When this is finalized, I'm going to store the IV's in a vault. Is this a good scheme?

For testing purposes I'm using one database with the encrypted values and IV's to start off with.

In their simplest form, this is what both tables look like. I'll call them A and B.

Table A:

ID | encrypted value

Table B:

ID | IV

ID on table A is associated with ID on table B.

Say if the encrypted values on table A were states, and I wanted to select all states that equal 'Maine', how would I get the decrypted values at the same time as doing the SELECT and having a WHERE?

Someone suggested it's going to be a JOIN like this:

code:
SELECT a.id, decrypt(a.encrypted_value, b.iv)
FROM tableA as a
JOIN tableB as b ON a.id = b.id
Which sort of makes sense, except I don't understand the decrypt part, and shouldn't there be a WHERE clause?

I also thought this would have something to do with AES_DECRYPT. I'm using MCRYPT_CAST_256 and MCRYPT_MODE_CBC with mcrypt_encrypt.

LP0 ON FIRE fucked around with this message at 17:13 on Nov 24, 2015

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

LP0 ON FIRE posted:

mysql/php/encryption advice needed!

I'm going to be brutally honest. You're obviously confused, and speaking as a professional who works with crypto, I strongly get the impression that you have no idea what you're doing.

If this is a personal project, that's fine, and I can give you some advice on how to experiment and start to get a handle on this stuff. This advice probably won't involve solving your current problem, because I think you need to experiment with something simpler to begin with, and frankly your problem is crazy and doesn't seem like it makes sense, on a fundamental level.

If this is a professional project, then I suspect you are way beyond your expertise and need to just hire a contractor who knows this stuff. You won't get it right by yourself. I'm not trying to be hurtful here, but there's a lot of fiddly little details involved in this sort of thing that without the right experience you're incredibly likely to get wrong and never notice until someone is suing your company or stealing all your customers' credit cards. If you're in the Pacific Northwest, I can give you some recommendations of contractors who will help you. If you're not, then someone else here can probably point you to a reliable contractor.

LP0 ON FIRE
Jan 25, 2006

beep boop
No I want to do it so I can learn. We're not storing credit cards, and everything is either hashed or has reversible encryption.

Trapick
Apr 17, 2006

LP0 ON FIRE posted:

No I want to do it so I can learn. We're not storing credit cards, and everything is either hashed or has reversible encryption.
Are you storing anything people would be angry about being public? Hint: yes you are. Email addresses, passwords, phone numbers, names, none of that do you want leaked and on your head if you get this wrong.

LP0 ON FIRE
Jan 25, 2006

beep boop

Trapick posted:

Are you storing anything people would be angry about being public? Hint: yes you are. Email addresses, passwords, phone numbers, names, none of that do you want leaked and on your head if you get this wrong.

I don't want to take "safe risks", but all that information is individually encrypted, and the IVs will be stored on a separate server.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Hey, we're talking encryption and security! That's awesome. I want to implement a basic client/server API to allow our client programs to send notifications to the server. The only big trick here is that only authorized clients should be able to use this service, and the details of the information they're sending should be kept private (i.e. not sent in the clear).

First off, I'm happy to use existing solutions so long as they're secure and open-source compatible; any recommendations? Failing that, here's the sketch of my design:

Clients that are authorized are provided with a client ID and a client private key, which they plug into their versions of the program.

Server-side: we expose an HTTP server that accepts three types of requests:

1) HTTP GET request for the server's public key ("Key Request").

2) HTTP GET request to request an authentication challenge ("Challenge"). This request will return a random string encrypted with the client's public key.

3) HTTP POST request to send a new notification ("Notification"). This request contains the following information:

- The decrypted random string from a Challenge request (usable once only, and only within a short time window)
- JSON string describing the notification, encrypted with the server's public key

All requests also include the client ID; we can revoke client IDs/keys if necessary by updating a table on the server side. We can also update the server's public/private keys at any time since each interaction with the server should involve first getting the new key -- it's not embedded into the client program anywhere.

The notification process should be fairly obvious from this: request the server's public key, request a challenge token, decrypt the token with the client's private key, encrypt the notification data with the server's public key, send both to the server. The server verifies the token matches what it encrypted and that the client is authorized, and if so, decrypts the notification data and takes appropriate action based on what it finds there. As far as I can tell, the client's information should remain private so long as they keep their private key, well, private -- which is down to proper operational security on their computers and is not something I think I should be particularly worried about.

This seems fairly straightforward, but I'm worried that I'm the guy going "computer security is easy! :downs:" while walking off a cliff into oceans full of Screaming Eels. So, uh, sanity check please?

nielsm
Jun 1, 2009



TooMuchAbstraction posted:

Hey, we're talking encryption and security! That's awesome. I want to implement a basic client/server API to allow our client programs to send notifications to the server. The only big trick here is that only authorized clients should be able to use this service, and the details of the information they're sending should be kept private (i.e. not sent in the clear).

If you have control over implementation of client and server, just go with proper TLS and verify the signatures of certificates on both ends.
Client connects to server, gets server's cert and public key, verifies it is valid. Client sends its own cert to server, server can verify identity of the client and authenticate it from this.
All of that built into the standard protocol.

Adbot
ADBOT LOVES YOU

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

TooMuchAbstraction posted:

This seems fairly straightforward, but I'm worried that I'm the guy going "computer security is easy! :downs:" while walking off a cliff into oceans full of Screaming Eels. So, uh, sanity check please?

The only thing I'd be worried about is added complexity over just a simple setup with HTTPS and Basic auth. HTTPS handles channel encryption and protection from MITM, while Basic auth allows you to validate that the client is authorized. This seems to satisfy your requirements and is a lot simpler to implement.

e:f,b

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply