• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

If anyone wants to throw me a bone, here's the function I'm currently in:

Note that gdb is dumping in AT&T syntax, I believe, so vs MSDN reference the order of operations will be switched.

Code:
Dump of assembler code for function read_six_numbers:
   0x0000000000401875 <+0>:     sub    $0x18,%rsp			# subtract 24 from rsp
   0x0000000000401879 <+4>:     mov    %rsi,%rdx			# move rsi into rdx
   0x000000000040187c <+7>:     lea    0x4(%rsi),%rcx			# load the contents of memory at rsi+4 into rcx
   0x0000000000401880 <+11>:    lea    0x14(%rsi),%rax			# load the contents of memory at rsi+20 into rax
   0x0000000000401884 <+15>:    mov    %rax,0x8(%rsp)			# move rax into the memory at rsp+8
   0x0000000000401889 <+20>:    lea    0x10(%rsi),%rax			# load the contents of memory at rsi+16 into rax
   0x000000000040188d <+24>:    mov    %rax,(%rsp)			# move rax into the memory at rsp
   0x0000000000401891 <+28>:    lea    0xc(%rsi),%r9			# load the contents of memory at rsi+12 into r9
   0x0000000000401895 <+32>:    lea    0x8(%rsi),%r8			# load the contents of memory at rsi+8 into r8
   0x0000000000401899 <+36>:    mov    $0x402b45,%esi			# move the constant 0x402b45 into esi
   0x000000000040189e <+41>:    mov    $0x0,%eax			# move the constant 0 into eax
   0x00000000004018a3 <+46>:    callq  0x400c80 <__isoc99_sscanf@plt>	# call sscanf
   0x00000000004018a8 <+51>:    cmp    $0x5,%eax			# compare eax with 5
   0x00000000004018ab <+54>:    jg     0x4018b2 <read_six_numbers+61>	# if > than then jump to exit
   0x00000000004018ad <+56>:    callq  0x401714 <explode_bomb>		# if <=, call explode_bomb
   0x00000000004018b2 <+61>:    add    $0x18,%rsp			# add 24 to rsp
   0x00000000004018b6 <+65>:    retq   					# return to caller
End of assembler dump.

So now we have a transliteration of what's going on. Now to figure out the semantics. We can guess by the call to sscanf and the cmp/jg (not to mention the function name) that it is expecting to scan six numbers out of a string. If this is x64 code (I can't tell, I thought x64 required a 32/48 byte stack reserve) the calling convention should be rcx/rdx/r8/r9 and then spill to stack. And we see us stuffing things into those registers, so it seems likely. The prototype for sscanf is const char* str, const char* fmt, ..., but if we're expecting to scan six numbers from the string we know those should be addresses in the varargs. From here we can unwind up the stack and see where the addresses come from, and then how they're used. I'm also betting if you look at the memory at 0x402b45 it will be a const char* that looks like "%d %d %d %d %d %d" or some such, too, eg the format string.

That's a start for now, I need to get back to work, good luck :).
 

mike23

Member
That gave me a linker error but I changed it to this:

Code:
void playGame()
{
   int symbol1, symbol2, symbol3, matches;
   float money, winnings;      
   money = 0;
    
    
   money = insertMoney(money);    
   symbol1 = spin(symbol1);
   symbol2 = spin(symbol2);
   symbol3 = spin(symbol3);
   showSpin(symbol1,symbol2,symbol3);
   matches = getMatches(symbol1,symbol2,symbol3);
   winnings = calcWinnings(matches, money);
   
   cout << "You Won $" << setprecision(2) << fixed << winnings << endl << endl; 
   
}

Code:
int spin(int symbol1)
{         
    symbol1 = rand() % BARS + CHERRIES;
    return symbol1;
}

And now it works!!!

Thank you so much for all your help Mike, if you weren't a monkey I'd kiss you.

Maybe you got the linker error because you didn't change your forward declaration. Other than that, I'm not sure why it didn't work.

Anyway, you can go further to fix the spin function by removing the argument too.

Code:
int spin()
{
   return rand() % BARS + CHERRIES;
}
 

Kinitari

Black Canada Mafia
Okay, totally need some help here.

I'm interning at a community centre and all they really ask me to do is make their databases better, so it's really good DB experience for me.

Problem is their databases are pretty messed up, and while normally I find some magic way to get them to work, right now I'm hitting a pretty annoying road block.

Background on the centre:
People come in, login on a computer and then have free reign of our services, when they leave they log out.
The Database tied to this login system logs their ID (which they get when they signup with us the first time) and their login times, and it is related to the main database which stores client information (like phone number, address etc).

What the boss wants:
The boss wants a little program that lets him pick a date, and a time frame and see all the clients who logged in during that time. Simple enough.

Where the problem is:
The database that logs in all the clients has the date and time broken up into different columns.

Day
Month
Year
Time in
Time out

As you can see, none of these are in a datetime format. I spent all of yesterday trying to find different ways around this, and eventually I decided that I was going to make it work like this:

Have a form that lets the user select a calendar date with a calendar control, and take just the day/month/year from that. Have two more controls for a 'beginning' and 'end' time. This was no problem - the next step was to combine all this information so that I now had two datetime variables labeled 'dateSelectFrom' and 'dateSelectTo' - that went off without a hitch as well. But I can't filter the datatable I created with this info.

Actually, writing this out and I guess having a day to refresh my mind has given my ONE idea on how to do it, but it isn't particularly efficient - it involves populating the datagridview (which I am using to display the information) and then filtering the results after the fact, which just makes the process take longer. Ideally I want my datatable to have a useable datetime column so that I can use it in the initial query.

For reference, the database is in access and the 'search' program is in c#/visual studio 2010. Any help would be much appreciated, hopefully I phrased the question well - this is one of my first times really asking for help in this fashion so I'm not sure how to communicate it right.
 

Zoe

Member
I would take the start date and end date from the form and break it up into the date parts to filter each column in the query. It would be something like

Code:
SELECT *
FROM Table
WHERE 
	Year BETWEEN @startYear AND @endYear
	AND
	Month BETWEEN @startMonth AND @endMonth
	AND
	DAY BETWEEN @startDay AND @endDay
	AND
	SomeConvertFunction(TimeIn) >= @startTime
	AND 
	SomeConvertFunction(TimeOut) <= @endTime

I'm not familiar enough with Access to know the exact syntax, but that's the general gist. From some quick searching, it seems like CDate might be able to convert the Time In and Time Out to proper times. If it tries to stick a date to the time, run your startTime and endTime parameters through the same function.

Edit: Just realized those month and day filters won't work. In that case I would just use CDate to build a datetime from all four columns and filter against that.
 
My cryptography professor asked the class to look up an authentication protocol and play around with it and see if we could get it to work on a local machine. I looked around and selected the Needham-Schroeder Protocal with RSA encryption and download the .java files from a website but I am having problems getting it to work. When I try to run it I get the following error "Error: argument 1 is the ip address of the server and argument 2 is port number" which is line 231 on the Client.java file. Where in the code am I supposed to enter it and is it possible to make it run on a local machine? Any help would be appreciated.

Here is the code


Client

Code:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.*;
import java.math.BigInteger;
import java.util.Random;
import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;

public class Client
{
	public static void main(String [] args)
	{
		if(args.length == 2)
		{
			try 
			{
				//initialize some stuff
				ArrayList<Data> currentDataList;
				
				BigInteger aliceKeyModulus = new BigInteger("20787141428342078048274333461999390004440124165601474280346321185566637476907080308933681326659948331748428020401773856811803037356697493317026702010094955786743702483484152241453332310568063763242568592507562033890762416337194928651202423381018314850660007265705059857334726669357575774268376467449862281057439870701736100337155514111649046576242513438365348522714173457334507703045417304030833122251753635872524615843288880711740690882652200896354480150304702388031551939235518674170228588727913717335939157810221009138514679246051975648113850229869626501879567775125480299962973715504201249230509946441302285355697");
				BigInteger alicePrivateKeyExponent = new BigInteger("2279268173765448111065495220378223241404195069258772818080910997443914993195512139707301738153690109586099512559426689275517900215835759753668216132025304061576517784554024718969187573183729896129836548907629900293559649111175103487915843178906535400107463146182409328086536549521698269891703210325384292104867096103827846888799268158567450511305602845709311570503034020968681393733363651386937091048057110894791739440567365094623025218773753281772720143271609051719080312690109382796101715182568467650096456233612044857618114294570726982336181729686821925847979267165110143723363506676702617326845942118072454736513");
				BigInteger bobKeyModulus = new BigInteger("22693090630676812786146318866995073138909126925799059956991682444955587061456928752760779259721475822341103571755438998441690662975224713300983820128166592670662571369434590273278538590192155275118237766270196531482648645979549986509685693733323045629042884111217757572462905555220745694278058223588580882744330279265143140532831712996945115780690852761116019998635100179468536555942163229670151476895927279128096217547176079111943526663139299328036187301163020785462500262316327052191926167164072317752942801277333302839226169364464196529039223854557270553026101415707512114886821563203575713919876171348696690191401");
				BigInteger bobPublicKeyExponent = new BigInteger("65537");

				KeyFactory keyFactory = KeyFactory.getInstance("RSA");
				BigInteger prime = new BigInteger("117849320114385963661082811775193929696410599606559407295715386891537435514103");
				BigInteger generator = new BigInteger("130");
				
				//use alices private key for decryption
				PrivateKey alicePrivateKey = keyFactory.generatePrivate(new RSAPrivateKeySpec(aliceKeyModulus, alicePrivateKeyExponent));
				Cipher decrypter = Cipher.getInstance("RSA");
				decrypter.init(Cipher.DECRYPT_MODE, alicePrivateKey);
				
				//use bobs public key for encryption
				PublicKey bobPublicKey = keyFactory.generatePublic(new RSAPublicKeySpec(bobKeyModulus, bobPublicKeyExponent));
				Cipher encrypter = Cipher.getInstance("RSA");
				encrypter.init(Cipher.ENCRYPT_MODE, bobPublicKey);
				
				//create connection to server
				Socket currentServer = new Socket(args[0], Integer.parseInt(args[1]));
				OutputStream serverOut = currentServer.getOutputStream();
				InputStream serverIn = currentServer.getInputStream();

				//generate diffie for random x
				//chosen prime is 264 bits, thats our maximum
				BigInteger x = new BigInteger(prime.bitCount(), new Random());
				BigInteger minimum = new BigInteger("2");
				while((x.compareTo(prime) >= 0)||(x.compareTo(minimum) <= 0))
				{
					x = new BigInteger(prime.bitCount(), new Random());
				}
				BigInteger px = generator.modPow(x, prime);
				Data NASent = new Data(px);

				System.out.println("NA Sent:");
				System.out.println(NASent);

				//alice identity is simply the string 'Alice'
				Data ASent = new Data("Alice");

				System.out.println("A Identity Sent:");
				System.out.println(ASent);

				currentDataList = new ArrayList<Data>();
				currentDataList.add(NASent);
				currentDataList.add(ASent);
				Data NAAKSent = new Data(currentDataList, encrypter);

				System.out.println("NAAK Sent:");
				System.out.println(NAAKSent);
				NAAKSent.write(serverOut);

				Data BNANBKReply = Data.read(serverIn);
				System.out.println("BNANBK Reply:");
				System.out.println(BNANBKReply);

				currentDataList = BNANBKReply.unnest(decrypter);
				
				if(currentDataList.size() == 3)
				{
					Data BReply = currentDataList.get(0);
					Data NAReply = currentDataList.get(1);
					Data NBReply = currentDataList.get(2);

					System.out.println("B Identity Reply:");
					System.out.println(BReply);
					
					System.out.println("NA Reply:");
					System.out.println(NAReply);

					System.out.println("NB Reply:");
					System.out.println(NBReply);

					//check that the nonce you sent bob is the one he sent back
					//also check that its actually bob
					if((NASent.equals(NAReply))&&(new String(BReply.getData()).equals("Bob")))
					{
						currentDataList = new ArrayList<Data>();
						currentDataList.add(NBReply);
						Data NBKSent = new Data(currentDataList, encrypter);

						System.out.println("NBK Sent:");
						System.out.println(NBKSent);
						NBKSent.write(serverOut);
						
						//get key from diffie y recieved from server
						BigInteger py = new BigInteger(new String(NBReply.getData()));
						BigInteger diffieKey = py.modPow(x, prime);
						
						System.out.println("connection setup with Key: " + diffieKey);
							
						byte[] newDiffieKey = getLast8Bytes(diffieKey.toByteArray());
						
						//create the session encrypter and decrypter
						Cipher sessionEncrypter = Cipher.getInstance("DES/ECB/PKCS5Padding");
						sessionEncrypter.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(newDiffieKey, "DES"));
						Cipher sessionDecrypter = Cipher.getInstance("DES/ECB/PKCS5Padding");
						sessionDecrypter.init(Cipher.DECRYPT_MODE, new SecretKeySpec(newDiffieKey, "DES"));
						
						System.out.println("Enter data to send to the server(type 'quit' to quit): ");

						//open up standard input
						BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
						
						String inputData = userInput.readLine();
						
						//initialize the data objects involved
						Data TSent;
						Data TKSent;
						Data TVKReply;
						Data TReply;
						Data VReply;
						
						//keep going until the user enters nothing
						while(!inputData.equals(""))
						{
							//encrypt and send over the data with the session key
							TSent = new Data(inputData);

							currentDataList = new ArrayList<Data>();
							currentDataList.add(TSent);
							TKSent = new Data(currentDataList, sessionEncrypter);
							TKSent.write(serverOut);
							
							//decrypt the reply with the session key
							TVKReply = Data.read(serverIn);
							currentDataList = TVKReply.unnest(sessionDecrypter);
							
							if(currentDataList.size() == 2)
							{
								TReply = currentDataList.get(0);
								VReply = currentDataList.get(1);
								
								//make sure it is the same data you sent to bob
								//and that bob calculated the length of the data correctly
								if((TSent.equals(TReply))&&(Integer.parseInt(new String(VReply.getData())) == inputData.length()))
								{
									System.out.println("server got the data correctly");
								}
								else
								{
									System.out.println("incorrect server response");
								}
							}
							else
							{
								System.out.println("incorrect amount of data in server response");
							}

							System.out.println("Enter some more data(type 'quit' to quit): ");
							inputData = userInput.readLine();
						}
						
						//finish up the connection by sending an empty string over to bob
						TSent = new Data("");
						
						currentDataList = new ArrayList<Data>();
						currentDataList.add(TSent);
						TKSent = new Data(currentDataList, sessionEncrypter);
						TKSent.write(serverOut);
							
						TVKReply = Data.read(serverIn);
						currentDataList = TVKReply.unnest(sessionDecrypter);
						if(currentDataList.size() == 2)
						{
							TReply = currentDataList.get(0);
							VReply = currentDataList.get(1);
							if((TSent.equals(TReply))&&(Integer.parseInt(new String(VReply.getData())) == 0))
							{
								System.out.println("server got the data correctly, connection terminated");
							}
							else
							{
								System.out.println("incorrect server response");
							}
						}
						else
						{
								System.out.println("incorrect amount of data in server response");
						}
					}
					else
					{
						System.out.println("wrong nonce reply or wrong identity");
					}
				}
				else
				{
					System.out.println("incorrect amount of data in step 2");
				}

				serverOut.close();
				serverIn.close();
				currentServer.close();
			}
			catch(UnknownHostException e)
			{
				System.out.println("Host Error");
				e.printStackTrace();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		else
		{
			System.out.println("Error: argument 1 is the ip address of the server and argument 2 is port number");
		}
	}

	//used for getting the last 8 bytes for the symmetric key
	static byte[] getLast8Bytes(byte[] inputArray)
	{
		byte [] newArray;
		
		if(inputArray.length > 8)
		{
			newArray = new byte[8];
			for(int i = 0; i < 8; i++)
			{
				newArray[i] = inputArray[inputArray.length - 8 + i];
			}
		}
		else
		{
			newArray = inputArray;
		}
		
		return newArray;
	}
}


Data

Code:
import javax.crypto.*;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.math.BigInteger;

public class Data
{
	//the data we send over the network consists of:
	//the type of data as one byte
	byte typeData;
	//the length of data as two bytes
	short lengthData;
	//the actual raw data
	byte[] currentData;

	//if the data is a string
	//generate the correct bytes
	Data(String inputData)
	{
		try
		{
			currentData = inputData.getBytes("US-ASCII");
		}
		catch(UnsupportedEncodingException e)
		{
			currentData = inputData.getBytes();
		}
		typeData = 0;
		lengthData = (short)currentData.length;
	}

	//if the data is a binary array
	//generate the correct bytes
	Data(byte[] inputData)
	{
		currentData = inputData;
		typeData = 1;
		lengthData = (short)currentData.length;
	}

	//if the data is an int
	//generate the correct bytes
	Data(int inputData)
	{
		currentData = String.valueOf(inputData).getBytes();
		typeData = 2;
		lengthData = (short)currentData.length;
	}

	//if the data is an big int
	//treat it as an int
	Data(BigInteger inputData)
	{
		currentData = inputData.toString().getBytes();
		typeData = 2;
		lengthData = (short)currentData.length;
	}

	//if the data is a structured data
	//generate the correct bytes
	Data(ArrayList<Data> inputDataList, Cipher encrypter)
	{
		byte[] currentBuffer = new byte[0];
		ByteBuffer tmpBuffer;

		for(int i = 0; i < inputDataList.size(); i++)
		{
			Data inputData = inputDataList.get(i);

			tmpBuffer = ByteBuffer.allocate(inputData.getLength() + 3);
			tmpBuffer.order(ByteOrder.LITTLE_ENDIAN);
			tmpBuffer.put(inputData.getType());
			tmpBuffer.putShort(inputData.getLength());
			tmpBuffer.put(inputData.getData());

			currentBuffer = concatByteArray(currentBuffer, tmpBuffer.array());
		}

		currentData = currentBuffer;

		//if you have passed on a cipher then encrypt the data
		//and define it as binary data
		if(encrypter != null)
		{
			try
			{
				currentData = encrypter.doFinal(currentData);
			} catch(Exception e) {
				System.out.println("Problems happened with the encrypter");
				e.printStackTrace();
			}
			typeData = 1;
			lengthData = (short)currentData.length;
		}
		else
		{
			typeData = 3;
			lengthData = (short)currentData.length;
		}
	}

	//read in a raw data object
	//nothing needs to be generated
	Data(byte inputType, short inputLength, byte[] inputData)
	{
		typeData = inputType;
		lengthData = inputLength;
		currentData = inputData;
	}

	//define get methods for all of the variables
	byte getType()
	{
		return typeData;
	}

	short getLength()
	{
		return lengthData;
	}

	byte getData(short i)
	{
		return currentData[i];
	}

	byte[] getData()
	{
		return currentData;
	}
	
	//get the internal data for a structured data object
	ArrayList<Data> unnest(Cipher decrypter)
	{
		ArrayList<Data> currentDataList = new ArrayList<Data>();
		
		try
		{
			byte[] currentDataArray = new byte[0];
			byte[] tmpDataArray;
			byte newTypeData;
			short newLengthData;
			byte[] newData;
			
			//if its encrypted, then unencrypt
			if((decrypter != null)&&(typeData == 1))
			{
				currentDataArray = decrypter.doFinal(currentData);
			}
			else if(typeData == 3)
			{
				currentDataArray = currentData;
			}
			
			//keep extracting data objects from the array while they exist
			while(currentDataArray.length >= 3)
			{
				newTypeData = currentDataArray[0];
				newLengthData = (short) (currentDataArray[1] + (currentDataArray[2] * 256));

				newData = new byte[newLengthData];
				System.arraycopy(currentDataArray, 3, newData, 0, newLengthData);
				
				tmpDataArray = new byte[currentDataArray.length - (newLengthData + 3)];
				System.arraycopy(currentDataArray, (newLengthData + 3), tmpDataArray, 0, tmpDataArray.length);
				currentDataArray = tmpDataArray;

				currentDataList.add(new Data(newTypeData, newLengthData, newData));
			}
		}
		catch(Exception e)
		{
		}
		
		return currentDataList;
	}

	//joins two byte arrays together
	byte[] concatByteArray(byte[] inputArray1, byte[] inputArray2)
	{
		byte[] currentArray = new byte[inputArray1.length + inputArray2.length];
		System.arraycopy(inputArray1, 0, currentArray, 0, inputArray1.length);
		System.arraycopy(inputArray2, 0, currentArray, inputArray1.length, inputArray2.length);

		return currentArray;
	}

	boolean equals(Data inputData)
	{
		if(typeData != inputData.getType())
		{
			return false;
		}
		if(lengthData != inputData.getLength())
		{
			return false;
		}
		if(!Arrays.equals(currentData, inputData.getData()))
		{
			return false;
		}
		return true;
	}

	public String toString()
	{
		String currentString = "";
		
		currentString += "Type: " + typeData + "\n";
		currentString += "Length: " + lengthData + "\n";
		
		currentString += "Data: ";
		for(int i = 0; i < currentData.length; i++)
		{
			if((typeData == 0)||(typeData == 2))
				currentString += String.format("%c", currentData[i]);
			else
				currentString += String.format("%x", currentData[i]);
		}
		currentString += "\n";
		
		return currentString;
	}

	//sends the data object out to the stream
	void write(OutputStream serverOut) throws IOException
	{
		ByteBuffer currentBuffer = ByteBuffer.allocate(lengthData + 3);
		currentBuffer.order(ByteOrder.LITTLE_ENDIAN);
		currentBuffer.put(typeData);
		currentBuffer.putShort(lengthData);
		currentBuffer.put(currentData);
		
		serverOut.write(currentBuffer.array());
		serverOut.flush();
	}

	//gets a data object from the stream
	static Data read(InputStream serverIn) throws IOException
	{
		byte tmpTypeData;
		short tmpLengthData;
		byte[] tmpData;

		int inputTypeData = serverIn.read();
		while(inputTypeData == -1)
			inputTypeData = serverIn.read();
		tmpTypeData = (byte)inputTypeData;

		int inputLengthData1 = serverIn.read();
		while(inputLengthData1 == -1)
			inputLengthData1 = serverIn.read();
		int inputLengthData2 = serverIn.read();
		while(inputLengthData2 == -1)
			inputLengthData2 = serverIn.read();
		tmpLengthData = (short) (inputLengthData1 + (inputLengthData2 * 256));

		int currentLength = tmpLengthData;
		int currentAmountRead = 0;
		tmpData = new byte[currentLength];
		int result;
		while(currentAmountRead != tmpLengthData)
		{
			result = serverIn.read(tmpData, currentAmountRead, currentLength);
			if(currentAmountRead != -1)
			{
				currentAmountRead += result;
				currentLength = tmpLengthData - currentAmountRead;
			}
		}

		return new Data(tmpTypeData, tmpLengthData, tmpData);
	}
}
 
Server

Code:
import java.io.*;
import java.net.*;

public class Server
{
	public static void main(String [] args)
	{
		if(args.length == 1)
		{
			try
			{
				ServerSocket parent = new ServerSocket(Integer.parseInt(args[0]));
				while(true)
					new ServerThread(parent.accept()).start();
				
			}
			catch(UnknownHostException e)
			{
				System.out.println("Problem with host name");
			}
			catch(IOException e)
			{
				e.printStackTrace();
			}
		}
		else
		{
			System.out.println("Error: argument 1 is port number to run server on");
		}
	}
}

Server Thread

Code:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.*;
import java.math.BigInteger;
import java.util.Random;
import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;

class ServerThread extends Thread
{
	private Socket currentClient;

	public ServerThread(Socket inputClient)
	{
		currentClient = inputClient;
	}

	public void run()
	{
		try
		{
			//initialize some stuff
			ArrayList<Data> currentDataList;
		
			BigInteger bobKeyModulus = new BigInteger("22693090630676812786146318866995073138909126925799059956991682444955587061456928752760779259721475822341103571755438998441690662975224713300983820128166592670662571369434590273278538590192155275118237766270196531482648645979549986509685693733323045629042884111217757572462905555220745694278058223588580882744330279265143140532831712996945115780690852761116019998635100179468536555942163229670151476895927279128096217547176079111943526663139299328036187301163020785462500262316327052191926167164072317752942801277333302839226169364464196529039223854557270553026101415707512114886821563203575713919876171348696690191401");
			BigInteger bobPrivateKeyExponent = new BigInteger("14196469517480486555979262511679372013093905653765592858640187810866138424594849046102799775231102846333565853462948311596668683206757068840914836526461420768489475617978375064683259893789587166403293256928327320357311317828334679599472111286334613237486140739976148476637726244083423908932452036390256307301561632033865396276603309084749721433173214691119537883679997971221006297575132286521642248981245001146145705392214439021282423179012708449672441210391671268322747519652388949759998138640385367537187305668394366057084604679896300024905671448647707485036281550888818193504219880855093383122886595460371284339457");
			BigInteger aliceKeyModulus = new BigInteger("20787141428342078048274333461999390004440124165601474280346321185566637476907080308933681326659948331748428020401773856811803037356697493317026702010094955786743702483484152241453332310568063763242568592507562033890762416337194928651202423381018314850660007265705059857334726669357575774268376467449862281057439870701736100337155514111649046576242513438365348522714173457334507703045417304030833122251753635872524615843288880711740690882652200896354480150304702388031551939235518674170228588727913717335939157810221009138514679246051975648113850229869626501879567775125480299962973715504201249230509946441302285355697");
			BigInteger alicePublicKeyExponent = new BigInteger("65537");

			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			BigInteger prime = new BigInteger("117849320114385963661082811775193929696410599606559407295715386891537435514103");
			BigInteger generator = new BigInteger("130");
			
			//use bobs private key for decryption
			PrivateKey bobPrivateKey = keyFactory.generatePrivate(new RSAPrivateKeySpec(bobKeyModulus, bobPrivateKeyExponent));
			Cipher decrypter = Cipher.getInstance("RSA");
			decrypter.init(Cipher.DECRYPT_MODE, bobPrivateKey);
			
			//use alices public key for encryption
			PublicKey alicePublicKey = keyFactory.generatePublic(new RSAPublicKeySpec(aliceKeyModulus, alicePublicKeyExponent));
			Cipher encrypter = Cipher.getInstance("RSA");
			encrypter.init(Cipher.ENCRYPT_MODE, alicePublicKey);
				
			OutputStream clientOut = currentClient.getOutputStream();
			InputStream clientIn = currentClient.getInputStream();

			Data NAAKReply = Data.read(clientIn);
			System.out.println("NAAK Reply:");
			System.out.println(NAAKReply);

			currentDataList = NAAKReply.unnest(decrypter);
			
			if(currentDataList.size() == 2)
			{
				Data NAReply = currentDataList.get(0);
				Data AReply = currentDataList.get(1);

				System.out.println("NA Reply:");
				System.out.println(NAReply);
				
				System.out.println("A Identity:");
				System.out.println(AReply);
				
				//check that its actually alice
				if(new String(AReply.getData()).equals("Alice"))
				{
					//generate diffie for random y
					//chosen prime is 264 bits
					BigInteger y = new BigInteger(prime.bitCount(), new Random());
					BigInteger minimum = new BigInteger("2");
					while((y.compareTo(prime) >= 0)||(y.compareTo(minimum) <= 0))
					{
						y = new BigInteger(prime.bitCount(), new Random());
					}
					BigInteger py = generator.modPow(y, prime);
					Data NBSent = new Data(py);

					System.out.println("NB Sent:");
					System.out.println(NBSent);
					
					//bob identity is simply the string 'Bob'
					Data BSent = new Data("Bob");

					System.out.println("B Identity Sent:");
					System.out.println(BSent);

					currentDataList = new ArrayList<Data>();
					currentDataList.add(BSent);
					currentDataList.add(NAReply);
					currentDataList.add(NBSent);

					Data NANBBKSent = new Data(currentDataList, encrypter);

					System.out.println("NANBBK Sent:");
					System.out.println(NANBBKSent);
					NANBBKSent.write(clientOut);
					
					Data NBKReply = Data.read(clientIn);
					System.out.println("NBK Reply:");
					System.out.println(NBKReply);
					
					currentDataList = NBKReply.unnest(decrypter);
					
					if(currentDataList.size() == 1)
					{
						Data NBReply = currentDataList.get(0);
						
						System.out.println("NB Reply:");
						System.out.println(NBReply);

						if(NBSent.equals(NBReply))
						{
							//get key from diffie x recieved from client
							BigInteger px = new BigInteger(new String(NAReply.getData()));
							BigInteger diffieKey = px.modPow(y, prime);
						
							System.out.println("connection setup with Key: " + diffieKey);
							
							byte[] newDiffieKey = getLast8Bytes(diffieKey.toByteArray());
							
							//create the session encrypter and decrypter
							Cipher sessionEncrypter = Cipher.getInstance("DES/ECB/PKCS5Padding");
							sessionEncrypter.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(newDiffieKey, "DES"));
							Cipher sessionDecrypter = Cipher.getInstance("DES/ECB/PKCS5Padding");
							sessionDecrypter.init(Cipher.DECRYPT_MODE, new SecretKeySpec(newDiffieKey, "DES"));
							
							//initialize the data objects involved
							Data TKReply;
							Data TReply;
							Data VSent;
							Data TVKSent;
							
							//decrypt the reply with the session key
							TKReply = Data.read(clientIn);
							currentDataList = TKReply.unnest(sessionDecrypter);
							
							if(currentDataList.size() == 1)
							{
								TReply = currentDataList.get(0);
								
								//quit when alice sends over an empty string
								while(!(new String(TReply.getData()).equals("")))
								{
									System.out.println("Data from client: " + new String(TReply.getData()));
									//encrypt and send over the data with the session key
									VSent = new Data(TReply.getData().length);
									
									currentDataList = new ArrayList<Data>();
									currentDataList.add(TReply);
									currentDataList.add(VSent);
									TVKSent = new Data(currentDataList, sessionEncrypter);
									TVKSent.write(clientOut);
							
									//decrypt the reply with the session key
									TKReply = Data.read(clientIn);
									currentDataList = TKReply.unnest(sessionDecrypter);
									
									if(currentDataList.size() == 1)
									{
										TReply = currentDataList.get(0);
									}
									else
									{
										System.out.println("incorrect amount of data in server response");
									}
								}
								
								//finish up the connection by sending an empty string and length 0 over to alice
								VSent = new Data(0);
								
								currentDataList = new ArrayList<Data>();
								currentDataList.add(TReply);
								currentDataList.add(VSent);
								TVKSent = new Data(currentDataList, sessionEncrypter);
								TVKSent.write(clientOut);
								
								System.out.println("client got the data correctly, connection terminated");
							}
							else
							{
								System.out.println("incorrect amount of data in client response");
							}
						}
						else
						{
							System.out.println("wrong nonce reply");
						}
					}
					else
					{
						System.out.println("incorrect amount of data in step 3");
					}
				}
				else
				{
					System.out.println("wrong identity");
				}
			}
			else
			{
				System.out.println("incorrect amount of data in step 1");
			}

			clientOut.close();
			clientIn.close();
			currentClient.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	//used for getting the last 8 bytes for the symmetric key
	static byte[] getLast8Bytes(byte[] inputArray)
	{
		byte [] newArray;
		
		if(inputArray.length > 8)
		{
			newArray = new byte[8];
			for(int i = 0; i < 8; i++)
			{
				newArray[i] = inputArray[inputArray.length - 8 + i];
			}
		}
		else
		{
			newArray = inputArray;
		}
		
		return newArray;
	}
}
 

Kinitari

Black Canada Mafia
I would take the start date and end date from the form and break it up into the date parts to filter each column in the query. It would be something like

Code:
SELECT *
FROM Table
WHERE 
	Year BETWEEN @startYear AND @endYear
	AND
	Month BETWEEN @startMonth AND @endMonth
	AND
	DAY BETWEEN @startDay AND @endDay
	AND
	SomeConvertFunction(TimeIn) >= @startTime
	AND 
	SomeConvertFunction(TimeOut) <= @endTime

I'm not familiar enough with Access to know the exact syntax, but that's the general gist. From some quick searching, it seems like CDate might be able to convert the Time In and Time Out to proper times. If it tries to stick a date to the time, run your startTime and endTime parameters through the same function.

Edit: Just realized those month and day filters won't work. In that case I would just use CDate to build a datetime from all four columns and filter against that.

Thanks so much, just reading into CDate right now - hopefully this pans out! My original plan was to combine the four columns into a datetime, this might be exactly what I need!
 

usea

Member
My cryptography professor asked the class to look up an authentication protocol and play around with it and see if we could get it to work on a local machine. I looked around and selected the Needham-Schroeder Protocal with RSA encryption and download the .java files from a website but I am having problems getting it to work. When I try to run it I get the following error "Error: argument 1 is the ip address of the server and argument 2 is port number" which is line 231 on the Client.java file. Where in the code am I supposed to enter it and is it possible to make it run on a local machine? Any help would be appreciated.

Here is the code

Client
It looks like you don't enter it in the code, you pass them as command line arguments when you run the program.
 
So i'm taking assembly next semester. From what I hear, it's quite hard. Any tips or advice? I'd like to start the semester with a decent understanding of the subject, as my next semester is pretty heavy and I want to minimize the struggle.
 

Toby

Member
god I hate git so much.
How come? I started using it recently and quite like it.

So i'm taking assembly next semester. From what I hear, it's quite hard. Any tips or advice? I'd like to start the semester with a decent understanding of the subject, as my next semester is pretty heavy and I want to minimize the struggle.
Do you know what architecture you'll be programming for? I could help you with it if you're using MIPS.
In my experience, it really depends on how deep you get into it. At my school, they went over it in a computer architecture class, so it wasn't the entire focus. The most difficult were recursive calls and dynamic memory management, IIRC.
 

gryz

Banned
Why? I started using it recently and quite like it.

lots of reasons, here's the most recent from today:
I go to push up some new code, do a pull on main branch, switch to my branch and do a rebase. rebase detects merge conflict, so I go in to resolve the conflict, my commit and the new commit are just randomly merged together, I have to go through line by line and split apart all the functions.

finally get that merge resolved(hopefully) and try to build again, now its failing because someone changed some enums and I have to do a new commit.

I really prefer the older style of checking files in/out and merging manually.
 
god I hate git so much.

Still have to dive into source control like git.
Only experience was year one dropbox.
Then after learning the hardway of using dropbox some tortoiseSvn experience.

I heard it mostly the git workflow you need to learn and feel.
 
git is like a divine gift from the heavens, but with great power comes great responsibility. The things you're complaining about have nothing to do with git per se and instead are related to having poor ancillary merge/resolve tools, or weak software process. The only way you'd be saved is if you used source control with exclusive checkout, which isn't used in any modern software engineering environment for good reason--it's a tremendous tax on productivity.
 

gryz

Banned
which isn't used in any modern software engineering environment for good reason--it's a tremendous tax on productivity.

you'd be surprised, previously I worked on a very large project that had exclusive checkout

also sounds like a typical git apologist answer :p
 

IceCold

Member
god I hate git so much.

wat. Git is the shit. Best thing ever.

svn > git


FIGHT!

There isn't even a fight.

Time to do each
C7Mz4.png


6adYs.png
 

usea

Member
Surely you are trolling. Distributed version control is like a god compared to any centralized one. Personally I use Mercurial just because I'm used to it, but git is basically the same thing.

I can't believe somebody actually wants checkouts and locks on files and stuff. If two people are breaking each other's code, the problem isn't with the source control system..

At work we use Fog Creek's source control service. They host all our remote repositories that we sync to/from. They went down for several hours because of the hurricane (diesel pumps failed because of flooding), so when we came into the office in the morning we couldn't access our remote repositories to sync with. What did we do? Nothing different. There is no "server" with distributed version control; all copies of the repository are equal. Somebody pushed their local copy onto a fileshare and we all synced with it. It took less than a minute.

One reason not to use git is if your project has a lot of large non-text files such as big textures, sounds, video, etc. Some places will use Perforce or whatever that is much better at that stuff.
 

IceCold

Member
Surely you are trolling. Distributed version control is like a god compared to any centralized one. Personally I use Mercurial just because I'm used to it, but git is basically the same thing.

I can't believe somebody actually wants checkouts and locks on files and stuff. If two people are breaking each other's code, the problem isn't with the source control system..

At work we use Fog Creek's source control service. They host all our remote repositories that we sync to/from. They went down for several hours because of the hurricane (diesel pumps failed because of flooding), so when we came into the office in the morning we couldn't access our remote repositories to sync with. What did we do? Nothing different. There is no "server" with distributed version control; all copies of the repository are equal. Somebody pushed their local copy onto a fileshare and we all synced with it. It took less than a minute.

One reason not to use git is if your project has a lot of non-text files such as images, sounds, video, etc. Some places will use Perforce or whatever that is much better at that stuff.

Yeah but usually you shouldn't store binaries in your version control repo (that includes external libraries too). You are much better off storing them in another server, and after cloning the repo, retrieving them using an automative build tool like make or ant.
 

leroidys

Member
Note that gdb is dumping in AT&T syntax, I believe, so vs MSDN reference the order of operations will be switched.

Code:
Dump of assembler code for function read_six_numbers:
   0x0000000000401875 <+0>:     sub    $0x18,%rsp			# subtract 24 from rsp
   0x0000000000401879 <+4>:     mov    %rsi,%rdx			# move rsi into rdx
   0x000000000040187c <+7>:     lea    0x4(%rsi),%rcx			# load the contents of memory at rsi+4 into rcx
   0x0000000000401880 <+11>:    lea    0x14(%rsi),%rax			# load the contents of memory at rsi+20 into rax
   0x0000000000401884 <+15>:    mov    %rax,0x8(%rsp)			# move rax into the memory at rsp+8
   0x0000000000401889 <+20>:    lea    0x10(%rsi),%rax			# load the contents of memory at rsi+16 into rax
   0x000000000040188d <+24>:    mov    %rax,(%rsp)			# move rax into the memory at rsp
   0x0000000000401891 <+28>:    lea    0xc(%rsi),%r9			# load the contents of memory at rsi+12 into r9
   0x0000000000401895 <+32>:    lea    0x8(%rsi),%r8			# load the contents of memory at rsi+8 into r8
   0x0000000000401899 <+36>:    mov    $0x402b45,%esi			# move the constant 0x402b45 into esi
   0x000000000040189e <+41>:    mov    $0x0,%eax			# move the constant 0 into eax
   0x00000000004018a3 <+46>:    callq  0x400c80 <__isoc99_sscanf@plt>	# call sscanf
   0x00000000004018a8 <+51>:    cmp    $0x5,%eax			# compare eax with 5
   0x00000000004018ab <+54>:    jg     0x4018b2 <read_six_numbers+61>	# if > than then jump to exit
   0x00000000004018ad <+56>:    callq  0x401714 <explode_bomb>		# if <=, call explode_bomb
   0x00000000004018b2 <+61>:    add    $0x18,%rsp			# add 24 to rsp
   0x00000000004018b6 <+65>:    retq   					# return to caller
End of assembler dump.

So now we have a transliteration of what's going on. Now to figure out the semantics. We can guess by the call to sscanf and the cmp/jg (not to mention the function name) that it is expecting to scan six numbers out of a string. If this is x64 code (I can't tell, I thought x64 required a 32/48 byte stack reserve) the calling convention should be rcx/rdx/r8/r9 and then spill to stack. And we see us stuffing things into those registers, so it seems likely. The prototype for sscanf is const char* str, const char* fmt, ..., but if we're expecting to scan six numbers from the string we know those should be addresses in the varargs. From here we can unwind up the stack and see where the addresses come from, and then how they're used. I'm also betting if you look at the memory at 0x402b45 it will be a const char* that looks like "%d %d %d %d %d %d" or some such, too, eg the format string.

That's a start for now, I need to get back to work, good luck :).

Thank you! I ended up getting through this phase and phase 3 today. Maybe I won't fail after all!
 

gryz

Banned
Surely you are trolling. Distributed version control is like a god compared to any centralized one. Personally I use Mercurial just because I'm used to it, but git is basically the same thing.

I can't believe somebody actually wants checkouts and locks on files and stuff. If two people are breaking each other's code, the problem isn't with the source control system..

At work we use Fog Creek's source control service. They host all our remote repositories that we sync to/from. They went down for several hours because of the hurricane (diesel pumps failed because of flooding), so when we came into the office in the morning we couldn't access our remote repositories to sync with. What did we do? Nothing different. There is no "server" with distributed version control; all copies of the repository are equal. Somebody pushed their local copy onto a fileshare and we all synced with it. It took less than a minute.

One reason not to use git is if your project has a lot of large non-text files such as big textures, sounds, video, etc. Some places will use Perforce or whatever that is much better at that stuff.

my old job was working on c firmware for enterprise data storage that was connected to bank atms etc, code bugs were extremely costly. in that case extremely strict version control was better.
 
my old job was working on c firmware for enterprise data storage that was connected to bank atms etc, code bugs were extremely costly. in that case extremely strict version control was better.

You're conflating policy with mechanism. There's nothing in git as a tool that prevents strict software engineering practice (whatever that means).

I work in the games industry and our current head sync is around 120G with probably 10G of churn a day, and strict dependencies between code and data for teams of hundreds of people. This is all stored in Perforce, but for pure engineering work we also have separate Git repos or layered Git on top of Perforce for more flexible localized change control.
 
How come? I started using it recently and quite like it.


Do you know what architecture you'll be programming for? I could help you with it if you're using MIPS.
In my experience, it really depends on how deep you get into it. At my school, they went over it in a computer architecture class, so it wasn't the entire focus. The most difficult were recursive calls and dynamic memory management, IIRC.

I'm doing an architecture course right now that focuses on assembly and embedded C programming. Recusive calls aren't bad in assembly. Its just looping the subroutine over and over and can be followed like a normal loop. Its the memory management and keeping track of the stack that really gets to me. Especially on the midterms with the insanity they can ask you.

Then again you may be talking about something else? Do you call the subroutine again before the RTS statement or after for the "recusive calls" that you mentioned? Cause if its before it seems like a normal loop to me.
 

Hari Seldon

Member
So I decided to get serious about learning a single language rather than splitting up my learning on a million different languages. My goal is to learn all of the basic programming tasks and then try and get some open source projects going for the resume. I decided on Python and I really love it so far. It came down to Python, C#, or Ruby. C# had the initial lead since I already have programmed in Java and C++, but I really don't like that it is tied to MS. Ruby seems entirely focused on web stuff and while I want to learn web stuff, I don't want to put all my eggs in that basket. Did I make the wrong choice?

Also, is there a guide somewhere for someone who has never ever done database programming? Preferably one in Python? I'd like to play around with some database stuff since it seems that small databases are used in nearly every serious programming application and I have no experience with them at all.
 

Zoe

Member
Also, is there a guide somewhere for someone who has never ever done database programming? Preferably one in Python? I'd like to play around with some database stuff since it seems that small databases are used in nearly every serious programming application and I have no experience with them at all.

I don't have a guide, but I would familiarize myself with SQL commands before mixing it up with apps.

People like to shit on it, but W3Schools is good for SQL reference.
 
Its the memory management and keeping track of the stack that really gets to me.

The stack is a pretty straightforward and elegant construct once you just sketch out everything that is happening. If we imagine a virtual machine with a stack pointer in register $sp and an argument calling convention that places all arguments on the stack, and some simple pseudo-instructions, we might have:

Code:
void foo( int n )
{
    n -= 1;
    printf( "n = %d\n", n );
    if ( n > 0 )
        foo( n );
}

.STR0:				# string constant in memory
    "n = %d\n"
foo:
    load $r1, ($sp)		# load n from stack
    sub $sp, $8, $sp		# make 8 bytes of space on the stack
    sub $r1, 1, $r1		# subtract 1 from n
    store ($sp), .STR0		# store our format string to the stack
    store 4($sp), $r1		# store n to the stack
    call printf	  		# call printf
    cmp $1, $r1			# compare n to 1
    jlt .L0 			# if less than 1 jump to epilog
    store ($sp), $r1		# store n to the stack
    call foo	 		# call foo
.L0:
    add $sp, $8, $sp		# pop our 8 bytes from the stack
    ret	     	 		# return to caller

Hopefully nothing too embarrassing that I missed there. With register calling conventions it gets even cleaner, and then various compilers will do various clever things if n is complete time visible.
 

Hari Seldon

Member
I don't have a guide, but I would familiarize myself with SQL commands before mixing it up with apps.

People like to shit on it, but W3Schools is good for SQL reference.

I'll take a look at that. I am pretty lost when it comes to databases. Not really the logical way as to how they work, but how they are managed by the code and which of the 300 different versions of database should I use and that kind of stuff.
 

Zoe

Member
I'll take a look at that. I am pretty lost when it comes to databases. Not really the logical way as to how they work, but how they are managed by the code and which of the 300 different versions of database should I use and that kind of stuff.

I tend to do everything via stored procedures (SQL Server). That way I'm never mixing statements with my code--I just pass parameters to the procedures to pull and push data.
 

Toby

Member
I'm doing an architecture course right now that focuses on assembly and embedded C programming. Recusive calls aren't bad in assembly. Its just looping the subroutine over and over and can be followed like a normal loop. Its the memory management and keeping track of the stack that really gets to me. Especially on the midterms with the insanity they can ask you.

Then again you may be talking about something else? Do you call the subroutine again before the RTS statement or after for the "recusive calls" that you mentioned? Cause if its before it seems like a normal loop to me.
IIRC you have to manage the stack with recursive calls. Saving your return address and any variables off to the stack, then loading them back when you return. I found it difficult to keep track of all that anyway. Eventually it came to me, but it was one of the more difficult assignments.
Loops were simply jumps to branches, as I recall.
 
My weekly java problems continue. I'm writing a program that prints the multiplication table from the numbers you input. Say you input 2 then a 5 you would get the multiplication table of that.

what my output should look like:
Code:
            1   2   
      ---------------------------   
        1 | 1   2
        2 | 2   4
        3 | 3   6
        4 | 4   8
        5 | 5   10

THis is what my output is:
Code:
         1   2
___________________________________________________________
   1 |   1   2   3   4   5
   2 |   2   4   6   8  10
   3 |   3   6   9  12  15
   4 |   4   8  12  16  20
   5 |   5  10  15  20  25

Heres the code where the problem is. I just cant figure out how to make it give me the output I want.
Code:
 public static void printMultiplicationTable(int tablewidth, int tablelength) { 
        System.out.format("      ");

        for(int i = 1; i<=tablewidth;i++ ) {

            System.out.format("%4d",i);

        }

        System.out.println();

        System.out.println("___________________________________________________________");

         

        for(int i = 1 ;i<=tablelength;i++) {

            // print left most column first

            System.out.format("%4d |",i);

            for(int j=1;j<=tablelength;j++) {

                System.out.format("%4d",i*j);

            }

            System.out.println();

        }
 

arit

Member
Code:
 public static void printMultiplicationTable(int tablewidth, int tablelength) { 

(...)

        for(int i = 1 ;i<=tablelength;i++) {

            // print left most column first

            System.out.format("%4d |",i);

            for(int j=1;j<=[B]tablelength[/B];j++) {

                System.out.format("%4d",i*j);

            }

            System.out.println();

        }

Using tablelength instead of tablewidth might be your mistake.
 

injurai

Banned
I'm finally done with Resolve/C++!!!!!!!

I'm FREEEEEEEEEEEEEEEEE!!!!!!!1!11!!!!

You will never deal with bull shit than I did... never
 

injurai

Banned
is linear programming useful for engineers? thinking of taking it as an elective. chemE major btw

here's the book they use:
http://www.amazon.com/dp/0534388094/?tag=neogaf0e-20

As in sequential programming as opposed to OOP? Because usually Sequential is much more used a low level circuit/mechanical/robotic level. Chemistry would probably use a more traditional OOP for simple mocking up of chemical reactions. However any knowledge you have could be a major asset so I would say take it. What other classes were you considering?
 
As in sequential programming as opposed to OOP? Because usually Sequential is much more used a low level circuit/mechanical/robotic level. Chemistry would probably use a more traditional OOP for simple mocking up of chemical reactions. However any knowledge you have could be a major asset so I would say take it. What other classes were you considering?

All I know is is that It's offered by the industrial engineering department.

they cover "Optimal allocation and control problems" "Convex sets" "properties of optimal solutions" "The simplex method", and a bunch of other things.

I was either gonna go with this or upper division e&m as an elective (because i like physics)
 

CrunchyB

Member
All I know is is that It's offered by the industrial engineering department.

they cover "Optimal allocation and control problems" "Convex sets" "properties of optimal solutions" "The simplex method", and a bunch of other things.

I was either gonna go with this or upper division e&m as an elective (because i like physics)

Linear programming is an optimization technique or algorithm. Very useful, but the word "programming" is a bit misleading.

http://en.wikipedia.org/wiki/Linear_programming
 
Linear Programming is an extremely useful optimisation technique in general and even if the only thing you get out the of the class is the ability to recognise when a given problem is best solved via LP you've learned something very valuable. I'd recomend taking it.
 
Linear Programming is an extremely useful optimisation technique in general and even if the only thing you get out the of the class is the ability to recognise when a given problem is best solved via LP you've learned something very valuable. I'd recomend taking it.

Absolutely. Many of the folks I consider the best programmers have strong mathematics backgrounds, and those of us without them (I could have minored, but never studied topology or set theory, anything past elementary ODEs basically) often lament that we should have studied mathematics instead of programming.
 
Absolutely. Many of the folks I consider the best programmers have strong mathematics backgrounds, and those of us without them (I could have minored, but never studied topology or set theory, anything past elementary ODEs basically) often lament that we should have studied mathematics instead of programming.

Also thinking of taking some more math related minor classes then programming classes.
I hope i can combine it with embedded programming classes. Embedded programming is something im becoming more interesting in lately after seeing what people make with them.

And because i have to run two minor periods i can hopefully convince the teacher about 2 projects i might do in the free space parts of the minors. One in embedded programming not sure yet what. And the other writing a software renderer, dont know how time consuming that is. Maybe i can combine the two. And make a simple game engine and tool chain as a second project. Maybe learn to use some blender on the side :)

personal thing i want to learn is how to use git(know it slightly) and vim and use linux some more. Just so i can be flexible when i enter the job market. I only have 1.5~2 year to go...
 
Anyone have a clue why a printf() command in a method in a .h file won't output anything, even when the entire program compiles and operates correctly otherwise?
 
Yeah, it was super stupid. I didn't realize that you had to re-build the .CPP file in order to get the changes from the .H file. Once I recompiled everything, it worked.

Sorry for wasting you two's time; stupid mistake.
 
Top Bottom