<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Hovsep Karaguezian's Development Blog : UNICODE</title><link>http://blogs.msdn.com/hovsep/archive/tags/UNICODE/default.aspx</link><description>Tags: UNICODE</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>UNICODE-ASCII-Arabic and conversion problems? Use this algorithm</title><link>http://blogs.msdn.com/hovsep/archive/2007/12/31/unicode-ascii-arabic-and-conversion-problems-use-this-algorithm.aspx</link><pubDate>Mon, 31 Dec 2007 11:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6915673</guid><dc:creator>hovsep</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/hovsep/comments/6915673.aspx</comments><wfw:commentRss>http://blogs.msdn.com/hovsep/commentrss.aspx?PostID=6915673</wfw:commentRss><description>&lt;P&gt;So, you've used Microsoft Office&amp;nbsp;applications like Excel or Access and SQL Server to store and retrieve Arabic text. There are times though, when your data seems to be corrupt or you get dummy latin characters when you're expecting the correct Arabic text. Providing configuration information regarding how to set SQL Server, Excel or Access to hold Arabic information correctly is not the topic of interest for this blog post. Instead, I'd like to provide you with an algorithm and sample VBA code to help you convert the latin text back to Arabic.&lt;/P&gt;
&lt;P&gt;There are many reasons for the Arabic text to appear in Latin. One of the reasons may be your SQL Server Collation settings, or the fact that you have used a VARCHAR (or in this context CHAR, TEXT, etc.) when you're supposed to use NVARCHAR (or NTEXT, NCHAR, etc.). The N prefix in the type makes sure that the information in the column is stored in UNICODE and hence, your Arabic text will surely display exactly as it is everywhere. However, if you are getting something like &lt;STRONG&gt;ÇáßãÈíæÊÑ&lt;/STRONG&gt; when you are supposed to get &lt;STRONG&gt;الكمبيوتر&lt;/STRONG&gt;, then it's already too late.&lt;/P&gt;
&lt;P&gt;Good news for you guys! I have figured out the conversion table between such Latin characters and the corresponding Arabic text in Unicode. The algorithm is simple, there is a difference in the ASCII codes between the Latin text and those in Arabic (based on codepage 1256: Arabic Windows). Unfortunately, this is not a constant value, as the order of characters is not the same either. Hence, in order to convert those Latin letters into UNICODE, all you have to do is scan the text taking one character at a time, then get the UNICODE value for the character and add the deficit&amp;nbsp;corresponding the range value from&amp;nbsp;the table below:&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class="" cellSpacing=3 cellPadding=3 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=style1 vAlign=top noWrap width=123 colSpan=2 class="style1"&gt;
&lt;P align=center&gt;ASCII range for Latin Text&lt;/P&gt;&lt;/TD&gt;
&lt;TD class=style1 vAlign=top noWrap width=123 colSpan=2 class="style1"&gt;
&lt;P align=center&gt;ASCII range for&amp;nbsp;Latin text&amp;nbsp;(in hex)&lt;/P&gt;&lt;/TD&gt;
&lt;TD class=style1 vAlign=top width=125 rowSpan=2 class="style1"&gt;
&lt;P align=center&gt;Deficit between ASCII and Unicode for Arabic&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=style3 vAlign=top noWrap width=71 class="style3"&gt;
&lt;P&gt;From&lt;/P&gt;&lt;/TD&gt;
&lt;TD class=style2 vAlign=top noWrap width=51 class="style2"&gt;
&lt;P&gt;To&lt;/P&gt;&lt;/TD&gt;
&lt;TD class=style2 vAlign=top noWrap width=79 class="style2"&gt;
&lt;P&gt;From&lt;/P&gt;&lt;/TD&gt;
&lt;TD class=style2 vAlign=top noWrap width=44 class="style2"&gt;
&lt;P&gt;To&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap width=71&gt;
&lt;P align=right&gt;192&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=51&gt;
&lt;P align=right&gt;214&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=79&gt;
&lt;P&gt;C0&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=44&gt;
&lt;P&gt;D6&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=125&gt;
&lt;P align=right&gt;1376&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap width=71&gt;
&lt;P align=right&gt;216&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=51&gt;
&lt;P align=right&gt;219&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=79&gt;
&lt;P&gt;D8&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=44&gt;
&lt;P&gt;DB&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=125&gt;
&lt;P align=right&gt;1375&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap width=71&gt;
&lt;P align=right&gt;221&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=51&gt;
&lt;P align=right&gt;223&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=79&gt;
&lt;P&gt;DD&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=44&gt;
&lt;P&gt;DF&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=125&gt;
&lt;P align=right&gt;1380&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap width=71&gt;
&lt;P align=right&gt;225&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=51&gt;
&lt;P align=right&gt;225&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=79&gt;
&lt;P&gt;E1&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=44&gt;
&lt;P&gt;E1&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=125&gt;
&lt;P align=right&gt;1379&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap width=71&gt;
&lt;P align=right&gt;227&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=51&gt;
&lt;P align=right&gt;230&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=79&gt;
&lt;P&gt;E3&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=44&gt;
&lt;P&gt;E6&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=125&gt;
&lt;P align=right&gt;1378&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap width=71&gt;
&lt;P align=right&gt;236&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=51&gt;
&lt;P align=right&gt;237&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=79&gt;
&lt;P&gt;EC&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=44&gt;
&lt;P&gt;ED&lt;/P&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap width=125&gt;
&lt;P align=right&gt;1373&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Note: This table is a draft one. Although I tried all possible Arabic characters, including special ones, I'm not sure&amp;nbsp;if this is the complete table. However, it is guaranteed that all textual characters are included.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Here's a VBA code you can use within Excel or Access to convert the Latin Text to Arabic. I have used Excel as an example:&lt;/P&gt;
&lt;P style="FONT-FAMILY: 'Courier New', Courier, monospace; BACKGROUND-COLOR: #eeeeee"&gt;Sub convert2ara()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each s In Selection&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strNew = ""&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For i = 1 To Len(s.Text)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; j = AscW(Mid(s.Text, i, 1))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Select Case j&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case &amp;amp;HC0 To &amp;amp;HD6: j = j + 1376&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case &amp;amp;HD8 To &amp;amp;HDB: j = j + 1375&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case &amp;amp;HDD To &amp;amp;HDF: j = j + 1380&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case &amp;amp;HE1: j = j + 1379&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case &amp;amp;HE3 To &amp;amp;HE6: j = j + 1378&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case &amp;amp;HEC To &amp;amp;HED: j = j + 1373&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Select&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strnew = strnew &amp;amp; ChrW(j)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cells(s.Row, s.Column + 1) = strnew&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;BR&gt;End Sub&lt;/P&gt;
&lt;P mce_keep="true"&gt;Here's also a T-SQL Stored Procedure that does the same thing:&lt;/P&gt;
&lt;P style="FONT-FAMILY: 'Courier New', Courier, monospace; BACKGROUND-COLOR: #eeeeee"&gt;CREATE PROCEDURE Convert2Ara&lt;BR&gt;&amp;nbsp;@Latin VarChar(100),&lt;BR&gt;&amp;nbsp;@Arabic NVarChar(100) = N'' OUTPUT &lt;BR&gt;AS&lt;BR&gt;BEGIN&lt;BR&gt;&amp;nbsp;DECLARE @ind int, @Len int, @Src int&lt;BR&gt;&amp;nbsp;SET @Len = Len(@Latin)&lt;BR&gt;&amp;nbsp;SET @Ind = 1&lt;BR&gt;&amp;nbsp;WHILE @ind &amp;lt;= @Len&lt;BR&gt;&amp;nbsp;&amp;nbsp;BEGIN&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SET @Src = ASCII(SUBSTRING(@Latin, @ind, 1))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set @Src = Case&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHEN @Src BETWEEN 192 and 214 THEN @Src + 1376&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHEN @Src BETWEEN 216 and 219 THEN @Src + 1375&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHEN @Src BETWEEN 221 and 223 THEN @Src + 1380&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHEN @Src = 225 THEN @Src + 1379&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHEN @Src BETWEEN 227 and 230 THEN @Src + 1378&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHEN @Src BETWEEN 236 and 237 THEN @Src + 1373&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;END&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SET @Arabic = @Arabic + NCHAR(@Src)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SET @Ind = @Ind + 1&lt;BR&gt;&amp;nbsp;&amp;nbsp;END&lt;BR&gt;END&lt;BR&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Try it and tell me if it works for you.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Special thanks to my friend, Mahdi Al-Saffar, whose request for some help inspired me to find a solution and publish this post.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6915673" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/hovsep/archive/tags/Character+Set/default.aspx">Character Set</category><category domain="http://blogs.msdn.com/hovsep/archive/tags/UNICODE/default.aspx">UNICODE</category><category domain="http://blogs.msdn.com/hovsep/archive/tags/ASCII/default.aspx">ASCII</category><category domain="http://blogs.msdn.com/hovsep/archive/tags/Conversion+Issues/default.aspx">Conversion Issues</category><category domain="http://blogs.msdn.com/hovsep/archive/tags/Excel/default.aspx">Excel</category><category domain="http://blogs.msdn.com/hovsep/archive/tags/Arabic/default.aspx">Arabic</category><category domain="http://blogs.msdn.com/hovsep/archive/tags/SQL+Server/default.aspx">SQL Server</category></item></channel></rss>