I have big problem in scraping webpage
I needed scraping img src adrress
but
result is
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII="
At first I didn't this but after I Knew that
but I can't decode
I try to search about base64 png image but I can't try to code at all.
I need your help
Give this a try. I wrote two functions DecodeBase64 and WriteByteArrayToFile. DecodeBase64 takes in a Base64 encoded string and returns the Byte() from this. WriteByteArrayToFile takes in a Byte() and a FilePath as string, and will write this Byte() to a file.
Update this section "YOURPATHGOESHERE\Picture.png" in the Example Sub to a valid file path on your computer, see if this code does what you are after. I'm getting a very small picture of what appears to be a square when running the code below.
Code
Option Explicit
'Decode Base64 string into a byte array
Public Function DecodeBase64(ByVal Base64String As String) As Byte()
With CreateObject("MSXML2.DOMDocument").createElement("b64")
.DataType = "bin.base64"
.Text = Base64String
DecodeBase64 = .nodeTypedValue
End With
End Function
'Take a byte array and write to a file
Public Sub WriteByteArrayToFile(FileData() As Byte, ByVal FilePath As String)
Dim FileNumber As Long: FileNumber = FreeFile
Open FilePath For Binary Access Write As #FileNumber
Put #FileNumber, 1, FileData
Close #FileNumber
End Sub
'Run from here
Sub example()
WriteByteArrayToFile DecodeBase64("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII="), "YOURPATHGOESHERE\Picture.png"
End Sub
Related
I am creating a project where a zip file is base 64 encoded and then the file is decoded and saved, but when I unzip the file it gives a corrupted file error.
Dim zip As New Xs_UnZipFilesCompat
''Encode()
Dim base64encoded As String
Using r As StreamReader = New StreamReader(File.OpenRead("E:\zip_test.zip"))
Dim data As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(r.ReadToEnd())
base64encoded = System.Convert.ToBase64String(data)
r.Dispose()
End Using
'decode --> write back
Using w As StreamWriter = New StreamWriter(File.Create("e:\stcRepositorio\Entrena_To_Art\Enviar\testDEco.zip"))
Dim data As Byte() = System.Convert.FromBase64String(base64encoded)
w.Write(System.Text.ASCIIEncoding.ASCII.GetString(data))
w.Dispose()
End Using
I can't find the solution
The encode is not correct. Specifically, this line:
Dim data As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(r.ReadToEnd())
You definitely don't want to read a file with a *.zip extension as if it were made of ASCII characters. Replace it with this:
Dim data As Byte() = System.IO.File.ReadAllBytes(fileName)
Which means you also no longer need the StreamReader, so we end up with this:
Public Function Encode(fileName As String) As String
Return Convert.ToBase64String(IO.File.ReadAllBytes(fileName))
End Function
Then the Decode would look like this:
Public Sub Decode(fileName As String, base64Data As String)
IO.File.WriteAllBytes(fileName, Convert.FromBase64String(base64Data))
End Sub
And you could call them like this:
Dim base64encoded As String = Encode("E:\zip_test.zip")
Decode("e:\stcRepositorio\Entrena_To_Art\Enviar\testDEco.zip", base64encoded)
Or we can write it without the methods like this:
Dim base64encoded As String = Convert.ToBase64String(IO.File.ReadAllBytes("E:\zip_test.zip"))
IO.File.WriteAllBytes("e:\stcRepositorio\Entrena_To_Art\Enviar\testDEco.zip", Convert.FromBase64String(base64encoded))
But it seems like that all reduces down to this:
IO.File.Copy("E:\zip_test.zip", "e:\stcRepositorio\Entrena_To_Art\Enviar\testDEco.zip")
I have folder in the name of Main1. And inside that folders, i have multiple folders. Like
Folders1
Folders2
Folders3
Folders4
Each folders have their own files. My requirement is to zip "Main1" folder including all the sub-folders and their files.
I dont want to use any third part tools. I'm planning to use namespace System.Compression with Gzip. Please guys advice.
ZipFile.CreateFromDirectory() can easily do this for you. Just pass it the path of your Day1 folder and it will zip the entire folder to a zip file. You can iterate over all the Day folders using System.IO.Directory class.
(Just realized that you want to stick to .NET Fx 2.0. There is no direct way of doing this in that version. You must either use 3rd-party lib, which you don't want to, or do low-level stuff).
Edit
If you're really inclined towards doing it by hand, here is a crude way:
Get the list of all directories (recursive) in your Day directory; call it DirList.
Get the list of all files (recursive) in your Day directory; call it FilesList.
Create a Dictionary(Of String, String) and store the name of each file in FilesList and the BASE64 representation of its contents; name as Key, content as Value.
Save the Dictionary to an XML file using .NET's built-in XML serialization.
At the very start of the file, inject the contents of DirList.
Save the file again. (you could do steps 4-6 in a single step too).
Read this file as binary and use GZip to compress the entire content.
Write it to a zip file.
To uncompress this file:
Open the file and use GZip to decompress and get your entire content.
Grab the list of directories from the top and create all recursively.
Read the remaining section in its entirety and use XML Serialization to create your Dictionary object from it.
Iterate through the Dictionary and create files using the Key part and then inject contents into the files by converting their Value from BASE64 back to binary.
Let me know if you have questions about any of these steps.
Edit 2
The following code is compiled against .NET 2.0 and will compress and decompress a directory:
Public Function ZipDirectory(DirPath As String) As Byte()
If Not Directory.Exists(DirPath) Then Return Nothing
Dim Directories = Directory.GetDirectories(DirPath, "*", SearchOption.AllDirectories)
Dim Files = Directory.GetFiles(DirPath, "*", SearchOption.AllDirectories)
Dim X As New XmlDocument
Dim RootNode = X.CreateElement("Content")
Dim DirsNode = X.CreateElement("Directories")
Dim FilesNode = X.CreateElement("Directories")
X.AppendChild(RootNode)
RootNode.AppendChild(DirsNode)
RootNode.AppendChild(FilesNode)
For Each d In Directories
Dim DirNode = X.CreateElement("Directory")
Dim PathAttrib = X.CreateAttribute("Path")
PathAttrib.Value = d.Replace(DirPath & "\", "") 'Create relative paths
DirNode.Attributes.Append(PathAttrib)
DirsNode.AppendChild(DirNode)
Next
For Each f In Files
Dim FileNode = X.CreateElement("File")
Dim PathAttrib = X.CreateAttribute("Path")
PathAttrib.Value = f.Replace(DirPath & "\", "") 'Create relative paths
FileNode.Attributes.Append(PathAttrib)
FileNode.InnerText = Convert.ToBase64String(File.ReadAllBytes(f))
FilesNode.AppendChild(FileNode)
Next
Using Mem As New MemoryStream()
X.Save(Mem)
Dim AllContentsAsByteArray = Mem.ToArray()
Dim CompressedContent = CompressArray(AllContentsAsByteArray)
Return CompressedContent
End Using
End Function
Public Sub UnzipDirectory(compressed() As Byte, outputPath As String)
If Not Directory.Exists(outputPath) Then Directory.CreateDirectory(outputPath)
Dim Uncompressed = DecompressArray(Compressed)
Dim X As New XmlDocument
Using Mem As New MemoryStream(Uncompressed)
X.Load(Mem)
Dim RootNode = X.FirstChild
Dim DirsNode = RootNode.FirstChild
Dim FilesNode = RootNode.FirstChild.NextSibling
For Each ChildDir In DirsNode.ChildNodes
Directory.CreateDirectory(Path.Combine(outputPath, DirectCast(ChildDir, XmlNode).Attributes.Item(0).Value))
Next
For Each ChildFile In FilesNode.ChildNodes
Dim FilePath = Path.Combine(outputPath, DirectCast(ChildFile, XmlNode).Attributes.Item(0).Value)
Dim Content = Convert.FromBase64String(DirectCast(ChildFile, XmlNode).InnerText)
File.WriteAllBytes(FilePath, Content)
Next
End Using
End Sub
Private Function CompressArray(ByVal content() As Byte) As Byte()
Using outFile As New MemoryStream()
Using Compress As New GZipStream(outFile, CompressionMode.Compress)
Compress.Write(content, 0, content.Length)
End Using
Return outFile.ToArray()
End Using
End Function
Private Function DecompressArray(ByVal content() As Byte) As Byte()
Using outFile As New MemoryStream()
Using inFile As New MemoryStream(content)
Using Compress As New GZipStream(inFile, CompressionMode.Decompress)
Dim buffer(1023) As Byte
Dim nRead As Integer
Do
nRead = Compress.Read(buffer, 0, buffer.Length)
outFile.Write(buffer, 0, nRead)
Loop While nRead > 0
End Using
End Using
Return outFile.ToArray()
End Using
End Function
The code should be used like this:
'To zip a directory
Dim Compressed = ZipDirectory("C:\SomeDir")
File.WriteAllBytes("C:\somedir.zip", Compressed)
'To unzip a zipped file
Dim Compressed = File.ReadAllBytes("C:\somedir.zip")
UnzipDirectory(Compressed, "C:\SomeDir2")
Below code is using System.IO.Compression
Example from MSDN site:
Link
Imports System
Imports System.Collections.Generic
imports System.IO
imports System.IO.Compression
Public Class CompressionSnippet
Public Shared Sub Main()
Dim path As String = "test.txt"
' Create the text file if it doesn't already exist.
If Not File.Exists(path) Then
Console.WriteLine("Creating a new test.txt file")
Dim text() As String = {"This is a test text file.", _
"This file will be compressed and written to the disk.", _
"Once the file is written, it can be decompressed", _
"imports various compression tools.", _
"The GZipStream and DeflateStream class use the same", _
"compression algorithms, the primary difference is that", _
"the GZipStream class includes a cyclic redundancy check", _
"that can be useful for detecting data corruption.", _
"One other side note: both the GZipStream and DeflateStream", _
"classes operate on streams as opposed to file-based", _
"compression data is read on a byte-by-byte basis, so it", _
"is not possible to perform multiple passes to determine the", _
"best compression method. Already compressed data can actually", _
"increase in size if compressed with these classes."}
File.WriteAllLines(path, text)
End If
Console.WriteLine("Contents of {0}", path)
Console.WriteLine(File.ReadAllText(path))
CompressFile(path)
Console.WriteLine()
UncompressFile(path + ".gz")
Console.WriteLine()
Console.WriteLine("Contents of {0}", path + ".gz.txt")
Console.WriteLine(File.ReadAllText(path + ".gz.txt"))
End Sub
Public Shared Sub CompressFile(ByVal path As String)
Dim sourceFile As FileStream = File.OpenRead(path)
Dim destinationFile As FileStream = File.Create(path + ".gz")
Dim buffer(sourceFile.Length) As Byte
sourceFile.Read(Buffer, 0, Buffer.Length)
Using output As New GZipStream(destinationFile, _
CompressionMode.Compress)
Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name, _
destinationFile.Name, False)
output.Write(buffer, 0, buffer.Length)
End Using
' Close the files.
sourceFile.Close()
destinationFile.Close()
End Sub
Public Shared Sub UncompressFile(ByVal path As String)
Dim sourceFile As FileStream = File.OpenRead(path)
Dim destinationFile As FileStream = File.Create(path + ".txt")
' Because the uncompressed size of the file is unknown,
' we are imports an arbitrary buffer size.
Dim buffer(4096) As Byte
Dim n As Integer
Using input As New GZipStream(sourceFile, _
CompressionMode.Decompress, False)
Console.WriteLine("Decompressing {0} to {1}.", sourceFile.Name, _
destinationFile.Name)
n = input.Read(buffer, 0, buffer.Length)
destinationFile.Write(buffer, 0, n)
End Using
' Close the files.
sourceFile.Close()
destinationFile.Close()
End Sub
End Class
Truly you would be better off using SharpLibZip
I need a VBA routine to calculate the MD5 hash of a file's contents. I located some examples (e.g., here) but I found that they crashed when the filename contained certain Unicode characters, so I am trying to tweak the code to avoid that.
This code does not result in an error, but it also doesn't return the correct MD5 hash. What's wrong?
Public Function FileToMD5Hex(sFileName As String) As String
Dim enc
Dim bytes
Dim outstr As String
Dim pos As Integer
Set enc = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider")
'Convert the string to a byte array and hash it
bytes = GetFileBytes(sFileName)
bytes = enc.ComputeHash_2((bytes))
'Convert the byte array to a hex string
For pos = 1 To LenB(bytes)
outstr = outstr & LCase(Right("0" & Hex(AscB(MidB(bytes, pos, 1))), 2))
Next
FileToMD5Hex = outstr
Set enc = Nothing
End Function
Private Function GetFileBytes(path As String) As Byte()
Dim fso As Object
Set fso = CreateObject("scripting.FileSystemObject")
Dim fil As Object
Set fil = fso.GetFile(path)
' Dim fpga As Variant
GetFileBytes = fil.OpenAsTextStream().Read(fil.Size)
Set fil = Nothing
Set fso = Nothing
End Function
There are some chars sequences that Scripting.FileSystemObject can't process properly as TextStream.
Use ADODB.Stream ActiveX to retrieve array of bytes from file. It works perfectly with both text and binary types of data, also it allows to change charset of the string (FSO only works with ASCII and Unicode, and only with files).
Function GetFileBytes(strPath As String) As Byte()
With CreateObject("ADODB.Stream")
.Type = 1 ' adTypeBinary
.Open
.LoadFromFile (strPath)
GetFileBytes = .Read()
End With
End Function
Another one ActiveX processing binary data is SAPI.spFileStream. One of the most significant advantages - it allows to load only the part of the file to the memory (in some cases when comparing large files it can help drastically increase performance, checking md5 by chunks).
Function GetFileBytes(strPath As String) As Byte()
Dim arrContent As Variant
With CreateObject("SAPI.spFileStream")
.Open strPath, 0
.Read arrContent, CreateObject("Scripting.FileSystemObject").GetFile(strPath).Size
.Close
End With
GetFileBytes = arrContent
End Function
I want to write a byte array to the end of an existing file. How to append byte array to file?
Here is the solution. Just use the following sub and provide the parameters as required:
Parameters description:
FilepathToAppendTo is the filepath you need to append the byte array
Content is your byte array
Private Sub AppendByteToDisk(ByVal FilepathToAppendTo As String, ByRef Content() As Byte)
Dim s As New System.IO.FileStream(FilepathToAppendTo, System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite)
s.Write(Content, 0, Content.Length)
s.Close()
End Sub
Use System.IO.FileStream class methods. Open/create a FileStream in append file mode.
System.IO.FileStream(filename,System.IO.FileMode.Append)
Dim bufData As Byte()
' write the entire buffer in one line of code
My.Computer.FileSystem.WriteAllBytes("BinaryFile.DAT", bufData, append := True)
Assumptions.
You want to use UTF8 encoding.
using( var stream = File.AppendText(#"D:\test.txt"))
{
stream.WriteLine(Encoding.UTF8.GetString( b ) );
}
VB Version:
Using stream = File.AppendText("D:\test.txt")
stream.WriteLine(Encoding.UTF8.GetString(b))
End Using
I have a encryption/decryption method that works just fine with one exception. When I attempt to read in encrypted text from a text file and then decrypt it I get the following error.
Invalid character in a Base-64 string
The strange thing is if I just read the encrypted text into a textbox and then copy and pate it into another text box that decrypts used the same decryption method it works just fine. No errors and the decryption proceeds. I am listing the decryption method and method used to read in the text file below.
Decryption Method
Public Shared Function DecryptUserString(ByRef cipheredText As String, ByRef password As String) As String
Dim RijndaelManagedObj As New RijndaelManaged
Dim RijndaelEncObj As ICryptoTransform, MD5Obj As New MD5CryptoServiceProvider
Dim DecryptedBytes As Byte(), EncryptedData As Byte()
Dim PasswordBytes As Byte() = New ASCIIEncoding().GetBytes(password)
Dim UTF8Encoding As System.Text.Encoding = System.Text.Encoding.UTF8
'A modified Base64 is sent with ~ and - so it can be sent as a form post
EncryptedData = Convert.FromBase64String(Replace(Replace(cipheredText, "~", "+"), "-", "="))
RijndaelManagedObj.BlockSize = 128
RijndaelManagedObj.KeySize = 128
RijndaelManagedObj.Mode = CipherMode.ECB
RijndaelManagedObj.Padding = PaddingMode.None
RijndaelManagedObj.Key = MD5Obj.ComputeHash(PasswordBytes)
RijndaelEncObj = RijndaelManagedObj.CreateDecryptor()
DecryptedBytes = RijndaelEncObj.TransformFinalBlock(EncryptedData, 0, EncryptedData.Length)
If DecryptedBytes.Length > 0 Then
DecryptUserString = UTF8Encoding.GetString(DecryptedBytes, 0, DecryptedBytes.Length)
If DecryptedBytes.Length = 0 Then DecryptUserString = New ASCIIEncoding().GetString(DecryptedBytes)
Else
DecryptUserString = ""
End If
End Function
Method to read text from file
Private Function ReadText(ByVal TextFilePath As String) As String
Using ReadStream As FileStream = File.OpenRead(TextFilePath)
Dim FileTextBuilder As New StringBuilder()
Dim DataTransit As Byte() = New Byte(ReadStream.Length) {}
Dim DataEncoding As New UTF8Encoding(True)
While ReadStream.Read(DataTransit, 0, DataTransit.Length) > 0
FileTextBuilder.Append(DataEncoding.GetString(DataTransit))
End While
Return FileTextBuilder.ToString()
End Using
End Function
Can't you use File.ReadAllText() method to read the whole file and then decrypt the same way you do with textboxes?
I know, if file is huge that's not a good idea, but you can give it a try to see if file is well saved or if you're reading it bad.