Excel - convert cell from hex string to SHIFT-JIS characters - excel

I need to convert space delineated hex values (ie. "B2 DD C0 B0 C8 AF C4 20 B9 DE B0 D1 81 48") in a column of cells to their SHIFT-JIS character equivalent in Excel. These strings may also include line breaks that need to be included in the translated cell value.
All of the functions and VBA code examples I've located so far appear to only work with western ascii values or unicode, which displays the incorrect characters. Converting by importing from CSV is not a viable solution, since the values are extracted from another hex dump in another worksheet (hex string extracted by using an offset table for length).
Tried using a sample VBA function to convert the hex characters, but it's not able to properly convert the SHIFT-JIS encoding.
=HexToString(SUBSTITUTE(I2,CHAR(32),"")) will result in "²ÝÀ°È¯Ä ¹Þ°ÑH" instead of "インターネット ゲーム?"
Public Function HexToString(InitialString As String) As String
Dim i As Long
For i = 1 To Len(InitialString) Step 2
HexToString = HexToString & Chr("&H" & (Mid(InitialString, i, 2)))
Next i
End Function

Related

Excel : Find only Hexa decimals from 1 cell

I'm a newbie on Excel.
So I have a list of some names ending with Hexa decimals. And some names, that doesn't have any.
My mission is to see only those names with Hexa decimals. (Mabye somehow filter them out)
Column:
BFAXSPOINTDEVBAUHOFLAN2AD
BFAXSQLBAUHOFLAN207
BFAXSQLDEVBAUHOFLAN27A
BFREPDEVBAUHOFLAN258
BFREPORTINGBAUHOFLAN20B
COBALTSEA02900
COBALTSEAVHOST900
DIRECTO8000
DIRECTO9000
DIRECTODCDIRECTOLA009
DYNAMAEBSSISE006
SURVEYEBSSISE006
KVMSRV00",
KVMSRV01",
KVMSRV02",
ASR
CACTI
DBSYNC",
DTV
and so on...
The Function HEX2DEC will help you achieve what you want - it attempts to convert a number as a hexidecimal, into a decimal. If it is not a valid Hex input, it will produce an error.
The key is understanding how many digits you expect your decimal to be - is it the last 5 characters; the last 10; etc. Also note that there is a risk that random text / numbers will be seen as hexidecimal when really that's not what it represents [but that's a problem with the question as you have laid it out; going solely based on the text provided, all we can see is whether a particular cell creates a valid Hexidecimal].
The full formula would look like this[assuming your data starts in A1, and that your Hexidecimal numbers are expected to be 6 characters long, this goes in B1 and is copied down]:
=ISERROR(HEX2DEC(RIGHT(A1,6)))
This takes the 6 rightmost characters of a cell, and attempts to convert it from Hex to Decimal. If it fails, it will produce TRUE [because of ISERROR]; if it succeeds, it will produce FALSE.
Then simply filter on your column to see the subset of results you care about.
Consider the following UDF:
Public Function EndsInHex(r As Range) As Boolean
Dim s As String, CH As String
s = r(1).Text
CH = Right(s, 1)
If CH Like "[A-F]" Or CH Like "[0-9]" Then
EndsInHex = True
Else
EndsInHex = False
End If
End Function
For the string to end in a hex, the last character must be a hex.

node.js: get byte length of the string "あいうえお"

I think, I should be able to get the byte length of a string by:
Buffer.byteLength('äáöü') // returns 8 as I expect
Buffer.byteLength('あいうえお') // returns 15, expecting 10
However, when getting the byte length with a spreadsheet program (libreoffice) using =LENB("あいうえお"), I get 10 (which I expect)
So, why do I get for 'あいうえお' a byte length of 15 rather than 10 using Buffer.byteLength?
PS.
Testing the "あいうえお" on these two sites, I get two different results
http://bytesizematters.com/ returns 10 bytes
https://mothereff.in/byte-counter returns 15 bytes
What is correct? What is going on?
node.js is correct. The UTF-8 representation of the string "あいうえお" is 15 bytes long:
E3 81 82 = U+3042 'あ'
E3 81 84 = U+3044 'い'
E3 81 86 = U+3046 'う'
E3 81 88 = U+3048 'え'
E3 81 8A = U+304A 'お'
The other string is 8 bytes long in UTF-8 because the Unicode characters it contains are below the U+0800 boundary and can each be represented with two bytes:
C3 A4 = U+E4 'ä'
C3 A1 = U+E1 'á'
C3 B6 = U+F6 'ö'
C3 BC = U+FC 'ü'
From what I can see in the documentation, LibreOffice's LENB() function is doing something different and confusing:
For strings which contain only ASCII characters, it returns the length of the string (which is also the number of bytes used to store it as ASCII).
For strings which contain non-ASCII characters, it returns the number of bytes required to store it in UTF-16, which uses two bytes for all characters under U+10000. (I'm not sure what it does with characters above that, or if it even supports them at all.)
It is not measuring the same thing as Buffer.byteLength, and should be ignored.
With regard to the other tools you're testing: Byte Size Matters is wrong. It's assuming that all Unicode characters up to U+FF can be represented using one byte, and all other characters can be represented using two bytes. This is not true of any character encoding. In fact, it's impossible. If you encode every characters up to U+FF using one byte, you've used up all possible values for that byte, and you have no way to represent anything else.

Matlab Split-String

Hello,
I have a little problem.
I have a txt file with over 200mb.
It looks like:
%Hello World
%second sentences
%third;
%example
12.02.2014
;-400;-200;200
;123;233;434
%Hello World
%second sentences
%third
%example
12.02.2014
;-410;200;20300
;63;23;43
;23;44;78213
..
... ...
I need only the Values after the semicolon like:
Value1{1,1}=[-400]; Value{1,2}=[-200]; and Value{1,3}=[200]
Value2{1,1}=[123]; Value{1,2}=[233]; and Value{1,3}=[434]
and so on.
Hase someone an ideas, how i can split the values in a cell array or vektor?
Thus, the variables must be:
Var1=[-400 -200 200;
434 233 434;
Var2=[
-410 200 20300;
63 23 43;
23 44 28213]
I will seperate, after every date in a another Value. Example when i have 55 Dates, i will have 55 Values.
shareeditundeleteflag
This could be one approach assuming a uniformly structured data (3 valid numbers per row) -
%// Read in entire text data into a cell array
data = importdata('sample.txt','');
%// Remove empty lines
data = data(~cellfun('isempty',data))
%// Find boundaries based on delimiter "%example"
exmp_delim_matches = arrayfun(#(n) strcmp(data{n},'%example'),1:numel(data))
bound_idx = [find(exmp_delim_matches) numel(exmp_delim_matches)]
%// Find lines that start with delimiter ";"
matches_idx = find(arrayfun(#(n) strcmp(data{n}(1),';'),1:numel(data)))
%// Select lines that start with character ";" and split lines based on it
%// Split selected lines based on the delimiter ";"
split_data = regexp(data(matches_idx),';','split')
%// Collect all cells data into a 1D cell array
all_data = [split_data{:}]
%// Select only non-empty cells and convert them to a numeric array.
%// Finally reshape into a format with 3 numbers per row as final output
out = reshape(str2double(all_data(~cellfun('isempty',all_data))),3,[]).' %//'
%// Separate out lines based on the earlier set bounds
out_sep = arrayfun(#(n) out(matches_idx>bound_idx(n) & ...
matches_idx<bound_idx(n+1),:),1:numel(bound_idx)-1,'Uni',0)
%// Display results for verification
celldisp(out_sep)
Code run -
out_sep{1} =
-400 -200 200
123 233 434
out_sep{2} =
-410 200 20300
63 23 43
23 44 78213
A brute force approach would be to open up your file, then read each line one at a time. With each line, you check to see if the first character is a semi-colon and if it is, split up the string by the ; delimiter from the second character of the line up until the end. You will receive a cell array of strings, so you'd have to convert this into an array of numbers. Because you will probably have each line containing a different amount of numbers, let's store each array into a cell array where each element in this cell array will contain the numbers per line. As such, do something like this. Let's assume your text file is stored in text.txt:
fid = fopen('text.txt');
if fid == -1
error('Cannot find file');
end
nums = {};
while true
st = fgetl(fid);
if st == -1
break;
end
if st(1) == ';'
st_split = strsplit(st(2:end), ';');
arr = cellfun(#str2num, st_split);
nums = [nums arr];
end
end
Let's go through the above code slowly. We first use fopen to open up the file for reading. We check to see if the ID returned from fopen is -1 and if that's the case, we couldn't find or open the file so spit out an error. Next, we declare an empty cell array called nums which will store our numbers that you are getting when parsing your text file.
Now, until we reach the end of the file, get one line of text starting from the top of the file and we proceed to the end. We use fgetl for this. If we read a -1, this means we have reached the end of the file, so get out of the loop. Else, we check to see if the first character is ;. If it is, then we take a look at the second character until the end of this line, and split the string based on the ; character with strsplit. The result of this will be a cell array of strings where each element is the string representation of your number. You need to convert this cell array back into a numeric array, and so what you would need to do is apply str2num to each element in this cell. You can either use a loop to go through each cell, or you can conveniently use [cellfun](http://www.mathworks.com/help/matlab/ref/cellfun.html to allow you to go through each element in this cell and convert the string representation into a numeric value. The resulting output of cellfun will give you a numeric array representation of each value delimited by the ; character for that line. We then place this array into a single cell stored in nums.
The end result of this entire code will give you numeric arrays that are based on what you are looking for stored in nums.
Warning
I am assuming that your text file only has numbers delimited by ; characters if we encounter a line that starts with ;. If this is not the case, then my code will not work. I'm assuming this isn't the case!

How do I convert a 64bit number to hexadecimal in excel?

I'm trying DEC2HEX(1000000000050000000) but it comes out as #NUM! as the number is too large for this function.
Is there another function I could use to turn this number into hexadecimal?
If you want to convert a decimal number to a 64 bit hex string, assuming that the decimal number is in cell A1 you can use the following:
=CONCATENATE(DEC2HEX(A1/2^32),DEC2HEX(MOD(A1,2^32),8))
This will work up to decimal value of 18,446,744,073,709,500,000 or hex value of 0xfffffffffffff800.
Bonus:
To convert from hex string to decimal, assuming that the 64bit hex string is in cell A1 and contains 16-characters then you can use the following:
=HEX2DEC(LEFT(A1,8))*2^32+HEX2DEC(RIGHT(A1,8))
You can adjust the number of characters in the LEFT(text,[num_chars]) to better suit your needs.
If your hex string has a 0x then you can use the following:
=HEX2DEC(MID(A1,3,8))*2^32+HEX2DEC(RIGHT(A1,8))
I found a simple solution for converting HEX to DEC and vice versa without the limits of characters.
HEX to DEC: use DECIMAL(input number or cell coordinates, input base number)
Case 1: I want to convert hex value "3C" to decimal, the formula is DECIMAL(3C, 16).
Case 2: I want to convert binary value "1001" to decimal, the formula is DECIMAL(1001, 2).
DEC to HEX: use BASE(input number or cell coordinates, output base number)
Case 1:I want to convert number value "1500" to hexadecimal, the formula is BASE(1500, 16)
Case 2:I want to convert number value "1500" to binary, the formula is BASE(1500, 2)
The DEC2HEX function has a limit of 549,755,813,887, try this formula it works for numbers up to 281,474,976,710,655.
=DEC2HEX(A7/(16^9),3)&DEC2HEX(MOD(A7,16^9),9)
There is a free add-in available that will handle that: Xnumbers
Seems to work OK:
=cvDecBase("1000000000050000000",16) --> DE0B6B3AA5EF080
Long formula but it is working for 64-HEX characters:
=HEX2DEC(MID(A24,1,8))*2^512 *(4) +HEX2DEC(MID(A24,9,8))*2^512 *(2) +HEX2DEC(MID(A24,17,8))*2^512+HEX2DEC(MID(A24,25,8))*2^256+HEX2DEC(MID(A24,33,8))*2^128+HEX2DEC(MID(A24,41,8))*2^64+HEX2DEC(MID(A24,49,8))*2^32+HEX2DEC(MID(A24,57,8))
please note: (*4) = *4 (remove brackets) and: (*2) = *2 (remove brackets)
also note: all 64 character must be present like the following example:
0000000000000000000000000000000000000000000000000000000000000fd1

How do I keep all the leading zeros on a Hexadecimal Range in VBA?

I am trying to expand a range of Hexadecimal numbers. For example I have on column K ... 1880 and column L ...188A my range is 1880-188A When I expand the Range, starting On column M I get 1880 1881 1882 1883 1884 1885 1886 etc etc.
From one of the posting I copied and changed the VBA script to fit my case... and it works ... but found 2 issues. All my device range are 4 digit and I need to keep all leading zeros.
For example if my range is 0000 - 0005 .... it errors... will not work.
If my range is 0001 - 0005 then I get 1 2 3 4 5.... and I want to be 0001 0002 0003 0004 0005
Any help will be much appreciated..
Thanks, JCam
Here is the script that I use it ... as long as there are no leading zeros on my range
Sub FillHexNumbers()
Dim cellKValue As Long
Dim cellLValue As Long
Dim diffBetweenKAndL As Long
Dim iCtr As Long
cellKValue = CLng(Format("&h" & Cells(2, 11).Text, "###"))
cellLValue = CLng(Format("&h" & Cells(2, 12).Text, "###"))
diffBetweenKAndL = cellLValue - cellKValue
For iCtr = 0 To diffBetweenKAndL
Cells(2, 13 + iCtr).Value = Hex(cellKValue + iCtr)
Next
End Sub
The Analysis Toolpak contains functions to convert between DEC and HEX - for HEX you can specify the # of digits, e.g. =DEC2HEX(14,4) gives "000E". You may enable this package by "Tools/Add-Ins...". By adding columns containing DEC numbers and displaying the HEX aequivalent you can maybe solve your task without VBA at all ...
Hope that helps
Try this:
Dim i as Integer 'This is the number you want to format
Dim l as Integer 'The length you want your format in (suppose it's six)
Dim h as String
l = 6
i = 47 'Any integer between 0 and 16,777,215
h = Replace(Space(l - len(hex(i))), " ", "0") & hex(i) 'h = "00002F"
The variable h will return the format text "00002F".
Cheers,
Rick.
you have to format the data as a string. You can do this with a single quite ie '0045.
may be something like this:
Cells(2, 13 + iCtr).Value = "'" & Hex(cellKValue + iCtr)
If you format a cell as text, then add your hex value with leading zeroes, they should remain.
If you are dealing with hex values that have already lost their leading zeroes, you can manually fix them in a text editor, then format your new cells as text, and paste values.
Alternatively, you can define a custom number format for those cells by right-clicking on them, choosing Format Cells..., choose Custom, then enter a value like "0000" (if, say, you'd like padding to four chars). This will only affect hex values that don't have an alpha character. If you enter 000A, Excel should preserve the zeroes and treat it as a string automatically.
It's very important that you also correct the cell formatting because Excel will remove the leading zeros if the format is General or Number. Two ways to correct this are:
Prefix your value with a single quote ( ' )
Cells(2, 13 + iCtr).Value = "'" & ...
Enforce a specific format.
Cells(2, 13 + iCtr).NumberFormat = "#" ' Text format
As for the challenge of adding the leading 0's. I've got three solutions for you.
Set the number format such that it displays the leading 0's. Note that this may not be the ideal solution if you really need the stored value to include the leading 0's.
Cells(2, 13 + iCtr).NumberFormat = "000000"
Use a binary Or with the value &H10000000 and then use Mid() or Right() to get rid of the leading 1. This has the disadvantage that your number can't be more than 7 digits in hex. However, given that the maximum column number in Excel 2016 is 16,384 (4 digits in hex) and the maximum row is 1,048,576 (6 digits in hex). That's kind of a non-issue.
' Using Mid()
Cells(2, 13 + iCtr).Value = Mid(Hex(&H10000000 Or (cellKValue + iCtr)), 2)
' Desired # of digits = # of 0's ^^^^^^^
' Using Right()
Cells(2, 13 + iCtr).Value = Right(Hex(&H10000000 Or (cellKValue + iCtr)), 4)
' Desired # of digits ^
Use the String() and Len() functions to pad the value with 0's. This has the disadvantage you must convert the number to hex twice, or create another variable to hold the converted string.
Cells(2, 13 + iCtr).Value = String(5 - Len(Hex(cellKValue + iCtr)), "0") & Hex(cellKValue + iCtr)
' Desired # of digits ^
Personally, I prefer the Or and Mid() method. It will ensure your raw value includes the leading 0's and it has the least number of functions/operations (thus it will perform the fastest).

Resources